JavaScript继承主要是通过原型链来实现。
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}
function SubType(){
this.subproperty = false;
}
SubType.prototype = new SuperType();//这里可以想象成实例化一个SuperType构造函数,可以这样写:sub1 = new SuperType();
//根据原型对象中的规则,调用构造函数创建一个新实例之后,该实例内部就会包含一个指针(内部属性[[prototype]]),指向构造函数的原型对象。
//这里是SubType.prototype可以看成是sub1的一个别名,但是这个别名并不普通,而是一个构造函数的原型对象,所以此时这个原型对象就如同是将SuperType实例化,这个实例中包含SuperType的实例属性//property。然后这个SubType的原型对象就指向了SuperType的原型对象,这样就形成了一个简单的原型链。
var instance = new SubType();
alert(instance.getSuperValue()); //true
简单回顾一下构造函数:
原型和实例的关系,每一个构造函数都有一个原型对象,原型对象都包含着一个指向构造函数的指针(这个通过原型对象中的constructor属性实现),而实例都包含一个指向原型对象的内部指针。
如果让原型对象等于另一个类型的实例,那么原型对象将包含一个指向另一个原型的指针,另一个原型中包含着一个指向另一个构造函数的指针。加入另一个原型又是另一个类型的实例,那么层层递进,就构成了实例与原型的链条。
注意:
1.别忘记默认的原型(Object)
2.子类型有时候需要重写超类型中的某个方法,或者需要添加超类型当中不存在的某个方法,但是不管怎么样,给原型添加方法的代码一定要放在替换原型的语句之后。
因为要实现上面的原型继承以及原型链。
3.在通过原型链实现继承的时候,不能使用对象字面量创建原型方法,因为这样做会重写原型链。
原型链的问题:
1.包含引用类型值的原型属性会被所有实例共享。
2.在创建子类型的实例时,不能向超类型的构造函数中传递参数。