递归在对象属性取值一次运用
月初在关注的公众号上刷到了一个关于es6的面试。
let greeting = 'my name is ${name},age ${age},I am a ${obj.jobNamme}';
const employee = {
name:'xiaoming',
age:11,
job:{
jobNamme:'designer',
jobLevel:'senior',
}
}
const result = greeting.render(employee);
console.log(result) //'my name is xiaoming,age 11,I am a designer';
除了使用eval和with+eval的方式,也想通过常规思路,用正则的方式来试试。
第一步
将需要替换的字符串全筛选出来。
String.prototype.format = function(obj){
let str = this;
return str.replace(/\$\{(.*?)\}/g,function(match,key){
console.log(match,key);
});
}
key是动态的,使用[]方式取值
String.prototype.format = function(obj){
let str = this;
return str.replace(/\$\{(.*?)\}/g,function(match,key){
console.log(match,key);
return obj[key];
});
}
查看结果却是
值为 undefined是应该key为job.jobNamme,执行结果是employee[job.jobNamme],而employee根本没有这个属性,正常取值也是employee.job.jobNamme。混合用好像没有这种方式。 思索再三,决定用递归的方式取值,这样不管嵌套多少层,都能正常取值。 奉上代码
function getObjValue(obj,str){
let arr = str.split('.') //将 job.jobNamme切成数组赋值给arr = [job,jobNamme]
return getValue(obj,arr)
}
function getValue(obj,arr){
//先判断arr的长度和obj的值类型
if(typeof obj =='object'&&arr.length){ //如果是object
const key = arr.shift() //取出最前面的值,如 job,
obj = obj[key] // 得到 {jobNamme:'designer',jobLevel:'senior',}
// 将得到值{jobNamme:'designer',jobLevel:'senior'},和 arr = [jobNamme]作为参数传给下去
return getValue(obj,arr)
}else{
//如果是基本值类型,直接返回
return obj
}
}
// 调用
String.prototype.format = function(obj){
let str = this;
return str.replace(/\$\{(.*?)\}/g,function(match,key){
console.log(match,key);
return getObjValue(obj,key);
});
}
运行结果。