js--继承、克隆

222 阅读2分钟

1、继承的7种方式(继承:constructor中的属性 + 原型prototype对象)

  • 1)原型链式继承: 原型子类.prototype = 父类的一个实例。缺点: 只能继承prototype对象
  • 2)构造函数继承:子类调用 父类.call(this)。缺点:只能继承父类属性,不能继承prototype
  • 3)实例继承:子类return一个父类带参实例。二者都有(当方法使用)
  • 4)拷贝继承: 子类中用for...in一个父类实例,拷贝所有结果到子类.prototype上。缺点:有些属性父类不可遍历
  • 5)组合继承:1)+2) 父类.call()+子类.prototype = 一个父类实例、添加constructor属性 缺点:子类继承时,父类属性重复定义了
  • 6)寄生组合继承:复用1)继承属性,定义一个空类Super,Super.prototype=父类.prototype,子类.prototype=new Super()
  • 7)ES6 class extends继承: super()调用父类方法

2、克隆

  • 1)JSON.stringify()以及JSON.parse(),无法深克隆undefined值和内嵌函数function、正则表达式
var obj1 = { x: 1, y: 2, z: 3 }
var str = JSON.stringify(obj1);
var obj2 = JSON.parse(str);
  • 2)Object.assign(target, source)
var obj1 = {x: 1,y: 2,z: 3}
var obj2 = Object.assign({}, obj1);
  • 3)自定义递归克隆函数:
function deepClone(target) {
  let newObj; // 定义一个变量,准备接新副本对象
  // 如果当前需要深拷贝的是一个引用类型对象
  if (typeof target === 'object') {
    if (Array.isArray(target)) {// 如果是一个数组
      newObj = []; // 将newObj赋值为一个数组,并遍历
      for (let i in target) { // 递归克隆数组中的每一项
        newObj.push(deepClone(target[i]))
      }
    // 判断如果当前的值是null;直接赋值为null
    } else if(target===null) {
      newObj = null;
     // 判断如果当前的值是一个正则表达式对象,直接赋值
    } else if(target.constructor===RegExp){
      newObj = target;
  }else {
  // 否则是普通对象,直接for in循环递归遍历复制对象中每个属性值
    newObj = {};
    for (let i in target) {
    newObj[i] = deepClone(target[i]);
  }
}
// 如果不是对象而是原始数据类型,那么直接赋值
} else { newObj = target; }
// 返回最终结果 return newObj;
}