javascript继承的方式

Author Avatar
高翔 2月 25, 2017

此继承非真正的继承

javascript继承的方式

javascript本身没有继承这一概念,都是通过模仿来实现继承的
下面几种方式可以实现javascript的继承

约定

1
2
3
4
5
6
7
function Aminal(){
this.species = '动物';
}
function Cat(name,color){
    this.name = name;
    this.color = color;
}

1. 利用apply和call的构造函数继承

1
2
3
4
5
6
7
function Cat(name,color){
    Animal.apply(this, arguments);
    this.name = name;
    this.color = color;
  }
  var cat1 = new Cat("小乔","黑色");
  alert(cat1.species); // 动物

使用call或apply方法,将Animal对象的构造函数绑定在子对象上,这样子对象的实例就可以访问到Animal的属性


缺点:

  • 并没有链接到父级的原型链,在父级原型中定义的东西不会被子类看到

2.原型继承

1
2
3
4
Cat.prototype = new Animal();
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("小乔","黑色");
  alert(cat1.species); // 动物

让Cat的prototype指向一个Animal的实例,就能顺着原型链得到Animal的所有属性和方法,
但是构造函数的实例cat1的constructor也会指向Animal了。不能让cat1称为Animal生成的吧,所以我们手动矫正,

1
Cat.prototype.contructor = Cat;

缺点:

  • 包含引用类型值的属性会被原型共享——有被修改的风险
  • 同时继承了两个对象的属性,即添加到this的属性和原型的属性。在绝大多时候不需要这些自身属性
  • 不支持将参数传入父级构造函数

3空对象中介继承

1
2
3
4
var F = function(){};
  F.prototype = Animal.prototype;
  Cat.prototype = new F();
  Cat.prototype.constructor = Cat;

F作为一个空的对象,几乎会没有占用内存,并且,由于有了F这个中介,改变Cat.prototype也不会改变Animal.prototype对象

组合继承

使用原型链实现对原型属性的和方法的继承,通过借用构造函数来实现对实例属性的继承。

1
2
3
4
5
6
7
function Cat(name,color){
  Animal.apply(this, arguments);
  this.name = name;
  this.color = color;
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

因为这里先使用了Animal的构造函数又将Animal的实例作为了构造函数的原型。故对象本身的属性在对象的原型中也会同时拥有一套。