deepClone, deepGetter

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)