Blog-JS的承拓展

const _String = Object.prototype.toString;

// 获取类型
function getType(item) {
  return _String.call(item).slice(8, -1);
}
// 判断类型
function isType(item, type) {
  return item && type && item === type;
}

// 考虑值是否是简单对象
// 1,该对象的返回原先必须是对象原型链,就是他自身
// 2.是否为window对象
// 3.是否object类型
function isPlianObejct(obj) {
  return (
    Object.getPrototypeOf(obj) === Object.prototype &&
    isWindow(obj) &&
    isType(obj, 'Object')
  );
}
// 考虑window是否为window(undefined)的情况
function isWindow(obj) {
  return obj != null && obj === obj.window;
}

// 拓展方法
function extend() {
  let target = arguments[0] || {},
    i = 1,
    lens = arguments.length,
    deep = false;

  let options, //待拷贝容器
    name, // 待拷贝容器的子项名称
    src, // 目标的子项内容
    copy, // 待拷贝容器的子项拷贝对象
    copyIsArr, // 拷贝对象是否为数组
    clone; // 需要再拷贝的内容

  // 如果参数第一个布尔值的话,则判断是否需要深拓展拷贝
  if (typeof target === 'boolean') {
    deep = target;
    //   将被拷贝值往后退一位
    target = arguments[1];
    // 同时被拷贝的项也往后推一位
    i++;
  }
  // 如果目标值不是对象,而且也不是方法的话,必须初始化为对象。
  if (typeof target !== 'object' && isType(target, 'Function')) {
    target = {};
  }

  // 如果参数长度等于初始化值的话
  //  待拷贝目标属于自身,同时将被拷贝内容序号往前推一位。
  if (i === lens) {
    target = this;
    i--;
  }

  //   开始正式拷贝
  for (; i < lens; i++) {
    //   将被拷贝对象赋值给otpions,同时必须保证对象不能为null
    if ((options = arguments[i]) != null) {
      // 循环options对象赋值给target
      for (name in options) {
        src = target[name];
        copy = options[name];

        // 如果拷贝对象和被拷贝的相等 则跳过该阶段的迭代,走一轮
        if (target === copy) {
          continue;
        }

        // 如果存在copy的值,且是深拷贝模式,且copy属于简单对象or属于数组对象
        if (
          deep &&
          copy &&
          isPlianObejct(copy || (copyIsArr = isType(copy, 'Array')))
        ) {
          if (copyIsArr) {
            // 如果为数组对象,则判断src是否为数组对象,
            // 如果是则赋值,不是则初始化数组[]
            clone = src && isType(src, 'Array') ? src : [];
          } else {
            // 同理
            // 如果src为简单对象,则判断src是否为数组对象,
            // 如果是则赋值,不是则初始化数组[]
            clone = src && isPlianObejct(obj) ? src : {};
          }
          //   递归该方法,不断往里面拷贝拓展
          target[name] = extend(deep, clone, copy);
        } else if (copy !== undefined) {
          target[name] = copy;
        }
      }
    }
  }
}

示例

let a = { name: 'Kisn' };
let b = {
  age: 25,
  job: {
    name: 'f2e'
  },
  love: ['code', 'js']
};

let c;

extends(true,c,a,b)

结果

image


Kisnnnn
46 声望5 粉丝

[链接]