构造函数的继承

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构造函数的继承相关的知识,希望对你有一定的参考价值。

今天介绍一下对象之间继承的五种方式

下面有两个构造函数:

function Animal(){
  this.species = "动物";
}
function Cat(name,color){
  this.name = name;
  this.color = color;
}

现在我们怎么使得Cat继承Animal?

以下我们用五种方法来实现继承

一、 构造函数绑定(call、apply)

这种方法直接简单,使用call或apply直接将父对象的构造函数绑定在子对象上

function Cat(name,color){
  Animal.apply(this, arguments);
  this.name = name;
  this.color = color;
}
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

二、 prototype模式

 javascript规定,每一个构造函数都会有一个prototype属性,指向另一个对象,而这个对象所有的方法和属性,都会被

构造函数的实例继承。

如果Cat的prototype对象,指向Animal的一个实例,那么所有Cat的实例,也就理所当然的能够继承Animal了。

Cat.prototype = new Animal(); 
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

我们来分析一下这段代码。

Cat.prototype = new Animal();这行代码让Cat的prototype对象指向了一个Animal的实例。

它相当于完全删除了prototype对象原来的值,然后赋予一个新的值。

但是,这样会有一个问题出现,就是Cat.prototype,constructor会指向Animal,所以,

Cat.prototype.constructor = Cat;这行代码让Cat.prototype的constructor指向Cat,不至于导致继承链的紊乱。

三、 直接继承prototype

我们可以把Animal对象中不变的属性写入Animal.prototype。这时候,我们就可以直接去Animal.prototype。

我们将Animal对象改写一下:

function Animal(){ }
Animal.prototype.species = "动物";

然后,将Cat的prototype对象指向Animal的prototype对象。

Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

虽然这种方法实现了继承,但是,当我们修改Cat.prototype时,会反映到Animal.prototype。

还有一个问题就是当添加了Cat.prototype.constructor = Cat;这行代码的时候,我们会发现

Animal.prototype.constructor = Cat,把Animal的constructor 也修改了,所以这种方法不是很完美。

四、 利用空对象作为中介

利用一个空的对象作为一个中介

var F = function(){};
F.prototype = Animal.prototype;
Cat.peotorype = new F();
Cat.prototype.constructor = Cat;

F是个空对象,几乎不占用内存,这时候修改了Cat.prototype的属性。

我们将上面的方法,封装成一个函数,便于使用。

fnntion extend(Child,Parent){
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.peotorype = new F();
    Child.prototype.constructor = Child;
    Child.uber = Parent.prototype;
}

使用方法:

extend(Cat,Animal);
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

控对象继承,可以说是一种很完美的继承方法,推荐大家使用。

五、 拷贝继承

如果把父对象的所有属性和方法,拷贝进子对象,也能够实现继承。

首先,还是把Animal的所有不变属性,都放到它的prototype对象上。

function Animal(){}
Animal.prototype.species = "动物";

然后,再写一个函数,实现属性拷贝的目的。

function extend2(Child, Parent) {
  var p = Parent.prototype;
  var c = Child.prototype;
  for (var i in p) {
    c[i] = p[i];
  }
  c.uber = p;
}

使用方法:

extend2(Cat, Animal);
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

 

以上是关于构造函数的继承的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

关于继承中静态代码块,构造代码块,构造函数执行顺序

C++提高:继承

C++提高:继承

什么是构造函数继承?

js组合继承(原型继承+借用构造函数继承)