**
原型链继承:
**
得到父类构造函数的方法
前面我们说到,所有的实例有一个内部指针,指向它的原型对象,并且可以访问原型对象上的所有属性和方法。doggie实例指向了Dog的原型对象,可以访问Dog原型对象上的所有属性和方法;如果Dog原型对象变成了某一个类的实例 aaa,这个实例又会指向一个新的原型对象 AAA,那么 doggie 此时就能访问 aaa 的实例属性和 AA A原型对象上的所有属性和方法了。同理,新的原型对象AAA碰巧又是另外一个对象的实例bbb,这个实例bbb又会指向新的原型对象 BBB,那么doggie此时就能访问 bbb 的实例属性和 BBB 原型对象上的所有属性和方法了。
这就是JS通过原型链实现继承的方法了
注意步骤是:
子类型的原型等于父类型的实例(如下代码:13行)
//定义一个 Animal 构造函数,作为 Dog 的父类
function Animal () {
this.superType = 'Animal'; //实例属性
}
Animal.prototype.superSpeak = function () { //原型属性
alert(this.superType);
}
function Dog (name) {//定义一个Dog的构造函数,作为子类
this.name = name;
this.type = 'Dog';
}
//改变Dog的prototype指针,指向一个 Animal 实例
Dog.prototype = new Animal(); // =============这里是原型链继承的关键
//上面那行就相当于这么写
//var animal = new Animal();
//Dog.prototype = animal;
Dog.prototype.speak = function () {
alert(this.type);
}
var doggie = new Dog('jiwawa');
doggie.superSpeak(); //Animal
解释一下。以上代码,首先定义了一个 Animal 构造函数,通过new Animal()得到实例,会包含一个实例属性 superType 和一个原型属性 superSpeak。另外又定义了一个Dog构造函数。然后情况发生变化,代码中加粗那一行,将Dog的原型对象覆盖成了 animal 实例。当 doggie 去访问superSpeak属性时,js会先在doggie的实例属性中查找,发现找不到,然后,js就会去doggie 的原型对象上去找,doggie的原型对象已经被我们改成了一个animal实例,那就是去animal实例上去找。先找animal的实例属性,发现还是没有 superSpeack, 最后去 animal 的原型对象上去找,诶,这才找到。
这就说明,我们可以通过原型链的方式,实现 Dog 继承 Animal 的所有属性和方法。
总结来说:就是当重写了Dog.prototype指向的原型对象后,实例的内部指针也发生了改变,指向了新的原型对象,然后就能实现类与类之间的继承了。(但是如果在重写原型对象之前,产生的实例,其内部指针指向的还是最初的原型对象。这个我下次再发篇文章讲。js 继承之借用构造函数继承)
**
借用构造函数继承:
**
这是假的继承
为了得到父构造函数的属性
在子类型构造函数中借用call()方法去调用父类型的方法
**
组合继承:
**
原型链继承和借用构造函数继承的组合继承
这样就可以达到父类构造函数的属性和方法都可见