前提: 组合指的是什么?就是这两部分的组合:构造函数属性的继承和建立子类和父类原型的链接。
借用构造函数继承
最简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上
function Super(name){
this.name=name;
this.friends = ['小红','小强'];
}
Super.prototype.sayName = function(){
alert(this.name)
};
function Sub(name){
Super.apply(this,arguments);
}
var instance1 = new Sub('小明');
var instance2 = new Sub('小明');
instance1.friends.push('张三');
console.log(instance1.friends);//["小红", "小强", "张三"]
console.log(instance2.friends);//["小红", "小强"]
缺点: 没办法继承超类中的原型属性和方法
原型链继承
function Super(){
this.name="小明";
}
Super.prototype.sayName = function(){
alert(this.name)
};
function Sub(){}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;
//此句的作用是为了不让继承链的紊乱,因为任何一个prototype对象都有一个constructor属性,指向它的构造函数,
//并且每一个实例也有一个constructor属性,默认调用prototype对象的constructor属性,
//所以new Animal()的constructor指向Super,导致Sub.prototype.constructor改而指向了Super 为了不导致紊乱 所以要手动指回
var instance = new Sub();
instance.sayName();//小明
缺点:
1.当父类中包含引用类型属性值时,其中一个子类的多个实例中,只要其中一个实例引用属性只发生修改一个修改,其他实例的引用类型属性值也会立即发生改变
2.原因是父类的属性变成子类的原型属性
组合式继承
(原型继承+借用构造函数继承)
function Super(){
this.name="小明";
this.friends = ['小红','小强'];
}
Super.prototype.sayName = function(){
alert(this.name)
};
function Sub(){
Super.call(this);
}
Sub.prototype = new Super();
var instance1 = new Sub();
var instance2 = new Sub();
instance1.friends.push('张三');
console.log(instance1.friends);//["小红", "小强", "张三"]
console.log(instance2.friends);//["小红", "小强"]
instance1.sayName();//小明
instance2.sayName();//小明
缺点:
1.两次调用父构造函数 并且子类的自由属性和原型链上的属性会重复覆盖 (打印instance1对象 instance1.prototype和instance1都有一个name属性)
2.同原型链继承的第一个缺点
寄生组合式继承
寄生组合式继承 两步:
1.在子类中调用父类的构造函数:
Super.apply(this,arguments)
2.建立子类和父类原型的链接
最简单的方法就是用Object.create()方法对父类的原型进行浅复制,赋给子类原型:
Sub.prototype=Object.create(Super.prototype); //相比之前的原型链继承方法:SubType.prototype=new SuperType();这里没有创建构造函数;
//寄生组合式继承函数
function inheritPrototype(sub,super){
var prototype=Object.create(super.prototype)
prototype.constructor = sub; //增强对象
sub.prototype = prototype; //最后指定对象
}
//最终的实现方法
function Super(name){
this.name=name;
}
Super.prototype.sayName=function(){console.log(this.name)}
function Sub(name,age){
Super.call(this,name);
this.age=age;
}
inheritPrototype(SubType,SuperType); //实现继承
//其实,说白了寄生组合式继承就是一个借用构造函数 + 相当于浅拷贝父类的原型对象
这种方式的高效率体现它只调用了一次Parent构造函数,并不会创建不必要的、多余的属性。与此同时,原型链还能保持不变;开发人员普遍认为寄生组合式继承是引用类型最理想的继承方式.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。