乐趣区

简单写一下JS的继承拓展方法extend

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)

结果

退出移动版