JS 继承

一、原型链继承
原理:利用原型让一个引用类型继承另一个引用类型的属性和方法。

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!');

你可能感兴趣的:(JS 继承)