搜索

首页  >  问答  >  正文

javascript - js如何实现这种操作,get(obj,'k1','k2','k3').then((v)=>console.log(v))

类似下面这种代码

get(obj,'k1','k2','k3')
    .then((v)=>console.log(v))
    .else(()=>console.log('值为空'));

实现下面这种代码的功能

if(obj && obj.k1 && obj.k1.k2 && obj.k1.k2.k3){
    console.log(obj.k1.k2.k3);
}else{
    console.log('值为空')
}
我想大声告诉你我想大声告诉你2715 天前996

全部回复(4)我来回复

  • 扔个三星炸死你

    扔个三星炸死你2017-06-26 10:55:44

    采用es6+promise实现方式

    // 功能实现
    function get(obj, ...props) {
      // 检查该对象是否拥有某个属性
      function hasProp(obj, prop) {
        return !!obj[prop]
      }
    
      return new Promise(function(resolve, reject) {
        let tempObj = {...obj}
        for (let i = 0; i < props.length; i++) {
          // 如果找到该属性,将该属性存储起来继续寻找下一个属性,直到循环结束
          if (hasProp(tempObj, props[i])) {
            tempObj = tempObj[props[i]]
          } else { // 找不到则返回错误信息
            return reject('找不到' + props[i] + '属性')
          }
        }
        return resolve(tempObj)
      })
    }
    // 使用
    let obj = {
      user: {
        name: 'anguer'
      }
    }
    get(obj, 'user', 'name').then(function(res) {
      console.log(res) // print 'anguer'
    }).catch(function(err) {
      console.log(err)
    })

    回复
    0
  • PHP中文网

    PHP中文网2017-06-26 10:55:44

    这样行不行

    function get (obj) {
        var scope = { obj: obj }
        var path = 'scope.obj.' + Array.prototype.slice.call(arguments, 1).join('.')
        var value = null
        var NONE = '值为空'
        try {
            value = (new Function('scope', 'return ' + path + ';'))(scope)
            if (value === null || value === undefined) {
                return NONE 
            } else {
                return value
            }
        } catch (e) {
            return NONE 
        }
    }
    
    var obj = { k1: { k2: { k3: 1}}}
    get(obj, 'k1', 'k2', 'k3') // 1
    get(obj, 'k1', 'k', 'k3')  // 值为空

    回复
    0
  • 高洛峰

    高洛峰2017-06-26 10:55:44

    class Tang {
      constructor() {
        this.obj = null;
        this.keys = [];
        this.thenF = [];
        this.elseF = [];
      }
      then(fn) {
        this.thenF.push(fn);
        return this;
      }
      _init() {
        let [obj, ...keys] = arguments;
        this.obj = obj;
        this.keys = keys;
        setTimeout(() => this._start(), 0)
        return this;
      }
    
      _start() {
        while(this.keys.length && this.obj) {
          this.obj = this.obj[this.keys.shift()];
        }
    
        if (!this.keys.length) {
          this.thenF.forEach(fn => fn(this.obj));
        } else {
          this.elseF.forEach(fn => fn());
        }
      }
      
      else(fn) {
        this.elseF.push(fn);
        return this;
      }
    }
    let obj = {k1:{k2:{k3:1}}};
    let tang = new Tang();
    let get = tang._init.bind(tang);
    get(obj,'k1','k2','k3')
        .then((v)=>console.log(v))
        .else(()=>console.log('值为空'));

    看到链式调用我就想到了之前的lazyman。
    实现的比较丑陋。。。

    回复
    0
  • phpcn_u1582

    phpcn_u15822017-06-26 10:55:44

    参考一下

    function get (obj, ...keys) {
      try {
        let value = keys.reduce((o, k) => o[k], obj)
        return {
          then (cb) {
            if (typeof cb === 'function') { cb(value) }
            return {else () {}}
          }
        }
      } catch (e) {
        return {
          then () {
            return {
              else (cb) {
                if (typeof cb === 'function') { cb(e) }
              }
            }
          }
        }
      }
    }

    回复
    0
  • 取消回复