美文网首页
deepClone, deepGetter

deepClone, deepGetter

作者: AAA前端 | 来源:发表于2022-01-18 11:12 被阅读0次

    deepClone

    var deepClone = function (data) {
        var type = getType(data);
        var obj;
        if (type === "array") {
            obj = [];
        } else if (type === "object") {
            obj = {};
        } else {
            // 不再具有下一层次
            return data;
        }
        if (type === "array") {
            for (var i = 0, len = data.length; i < len; i++) {
                obj.push(deepClone(data[i]));
            }
        } else if (type === "object") {
            for (var key in data) {
                obj[key] = deepClone(data[key]);
            }
        }
        return obj;
    };
    
    var getType = function (obj) {
        // toString会返回对应不同的标签的构造函数
        let toString = Object.prototype.toString;
        let map = {
            "[object Boolean]": "boolean",
            "[object Number]": "number",
            "[object String]": "string",
            "[object Function]": "function",
            "[object Array]": "array",
            "[object Date]": "date",
            "[object RegExp]": "regExp",
            "[object Undefined]": "undefined",
            "[object Null]": "null",
            "[object Object]": "object"
        };
        if (obj instanceof Element) {
            return "element";
        }
        return map[toString.call(obj)];
    };
    

    deepGetter

    1.数组的reduce方法

    deepGetter(obj, arr) {
          return arr.reduce(function(xs, x){
            return (xs && xs[x]) ? xs[x] : null
          }, obj)
        },
    // let newData = this.deepGetter(obj , [ 'template',  'pages', '0', 'elements', ]);
    // 可以取到对象里面 数组
    
    var deepGetter = function (obj, strOrArr) {
      let arr = strOrArr
      if (Object.prototype.toString.call(strOrArr) === '[object String]') {
        arr = []
        // obj.a.arr[1].name
        var list = strOrArr.split(/\.|\[|\]\.?/g)
        // 如果是 obj.a.arr[1] 得到的 数组会有一个空字符串 ['obj', 'a', 'arr', '1', '']
        // 如果是 obj[2] 会得到数字第一项是空字符串
        for (let i in list) {
          const item = list[i]
          //  不是 空字符串
          if (!(!item && Object.prototype.toString.call(item) === '[object String]')) {
            arr.push(item)
          }
        }
      }
      console.log(`%c obj, arr的值是:%o`, 'background-color:#0f0;color:#f00;font-size:20px;', obj, arr)
      return arr.reduce(function (xs, x) {
        return (xs && xs[x]) ? xs[x] : null
      }, obj)
    }
    
    deepGetter(obj, ['a', 'b', 'arr', '1', 'name'])
    deepGetter(obj, a.b.arr[1])
    
    1. Proxy代理监听
    /**
     * @param target
     * @param exec 取值属性
     * @returns {*}
     */
    function getter(target, exec = '_') {
      return new Proxy({}, {
        get: (o, n) => {
          return n === exec ?
            target :
            getter(typeof target === 'undefined' ? target : target[n], exec)
        }
      });
    }
    
    getter(address).province.city.district.name._ // 邗江区
    
    
    // ES5
    function getter(obj, arr) {
      return arr.length === 0 ? obj : getter(typeof obj === 'undefined' ? undefined : obj[arr[0]], arr.slice(1))
    }
     
    getter(address, ['province', 'city', 'district', 'name'])
    
    

    3.可选链操作符?. 目前主流的PC端浏览器均已支持

    address?.province?.city?.district?.name
    
    1. Lodash的get方法
    _.get(address, 'province.city.district.name')
    

    相关文章

      网友评论

          本文标题:deepClone, deepGetter

          本文链接:https://www.haomeiwen.com/subject/ralkhrtx.html