一、原型链继承
原理:利用原型让一个引用类型继承另一个引用类型的属性和方法。
function SuperFn() {
this.text= "hello world!";
}
SuperFn.prototype.say = function() {alert(this.text)};
function SubFn() {}
SubFn.prototype = new SuperFn();
var a = new SubFn();
a.say();
缺点:
1.超类型构造函数的属性会被所有实例所共享。
2.无法在不影响所有实例对象的情况下给超类型构造函数传递参数。
二、构造函数继承
原理:也叫伪造对象继承或者经典继承,即在子类型构造函数内部调用超类型构造函数,它解决了无法向超类型构造函数传参的问题。
function SuperFn(text) {
this.text = text;
}
SuperFn.prototype.say = function() {alert(this.text)};
function SubFn(text) {
SuperFn.call(this, text);
}
var a = new SubFn('hello world!');
a.say(); // 会报错
缺点:
1.无法继承超类型构造函数的原型属性。
三、组合继承
原理:组合使用原型链继承和构造函数继承,利用原型链继承方式实现对原型属性和方法的继承,利用构造函数继承方式实现对实例的属性和方法的继承。
function SuperFn(text) {
this.text = text;
}
SuperFn.prototype.say = function() {alert(this.text)};
function SubFn(text) {
SuperFn.call(this, text);
}
SubFn.prototype = new SuperFn();
var a = new SubFn('hello world!');
a.say();
缺点:
调用了两次超类型构造函数。
四、寄生组合继承(推荐)
解决了组合继承会调用两次超类型构造函数的缺陷。
function SuperFn(text) {
this.text = text;
}
SuperFn.prototype.say = function() {alert(this.text)};
function SubFn(text) {
SuperFn.call(this, text);
}
function inheritPrototype(SuperFn, SubFn) {
var proto = Object.create(SuperFn.prototype); //创建对象
proto.constructor = SubFn; //增强对象
SubFn.prototype = proto; //制定对象
}
inheritPrototype(SuperFn, SubFn);
SubFn.prototype.sleep = function() {alert('sleepping')}
var a = new SubFn('hello world!');