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)
function deepClone(target) {
let newObj
// 如果当前需要深拷贝的是一个引用类型对象
if (typeof target === 'object') {
if (Array.isArray(target)) {// 如果是一个数组
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
}