继承 8种方式
原型链继承
- 重点:子的原型对象为new一个父的实例
Child.prototype = new Parent();
-
借用构造函数继承
重点:在子构造函数内部调用父构造函数
Parent.call(this)
-
组合继承
重点:使用原型链继承共享的属性和方法,通过借用构造函数继承实例属性
function Child(name,age){
// 继承属性
Parent.call(this, name)
this.age=age
}
// 继承方法
Child.prototype = new Parent()
Child.prototype.constructor = Child;
缺点:无论在什么情况都会调用两次父构造函数,一次是创建子类型原型,另一次是在子构造函数内部
原型式继承
重点:执行对给定对象的浅复制
function object(obj){
function F(){}
F.prototype=obj
return new F();
}
var person1=object(person);
在ES5中Object.create()可替换上面的方法object()
var person1 = Object.create(person);
缺点:原型链继承多个实例的引用类型属性指向相同,存在篡改的可能;无法传递参数
寄生式继承
重点:在原型式继承的基础上,增强对象,返回构造函数
function createAnother(obj){
var clone=object(obj);
// ES5中用这个
// var clone=Object.create(obj);
// 增强对象
clone.sayHi=function(){};
return clone;
}
var person1=createAnother(person)
-
寄生组合式继承
重点:结合构造函数传递参数和寄生模式实现继承
// 借用构造函数增强子类实例属性(支持传参和避免篡改)
function Child(name,age){
// 继承属性
Parent.call(this, name)
this.age=age
}
function inheritPrototype(Child, Parent){
var prototype=Object.create(Parent.prototype);
prototype.constructor=Child;
Child.prototype=prototype;
}
// 将父类原型指向子类,这样子类就能使用父类原型链的属性/方法
inheritPrototype(Child, Parent);
混入方式继承多个方式
重点:利用Object.assign将父类原型上的方法拷贝到子类原型上,这样子类实例实例就可以使用父类的方法
Object.assign(Child.prototype, Parent.prototype);
Child.prototype.constructor=Child;
ES6类 extends
重点:使用extends表明继承自哪个父类,并且在子类构造函数中必须使用super,可以看做是Parent.call(this,value)
class Parent{
constructor(value){
this.val=value
}
}
class Child extends Parent{
constructor(value){
super(value)
this.val = value
}
}