递归在对象属性取值一次运用

135 阅读1分钟

递归在对象属性取值一次运用

月初在关注的公众号上刷到了一个关于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);
      });
  }

企业微信截图_16552635668662.png

key是动态的,使用[]方式取值

    String.prototype.format = function(obj){
    let str = this;
    return str.replace(/\$\{(.*?)\}/g,function(match,key){
        console.log(match,key);
        return obj[key];
      });
  }

查看结果却是

企业微信截图_16552699856584.png

值为 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);
        });
    }

运行结果。

企业微信截图_16552700464698.png