通过示例了解基于原型继承
原型链的关系
构造函数都有原型对象
原型(指针 => 构造函数)
实例(指针 => 原型对象)
假如让对象的原型等于另一个对象的实例,会发生什么?
此时对象的原型就包含一个指向另一个对象的原型的指针。
另一个对象的原型又包含一个指向该构造函数的指针。
用下面的示例来展现构造函数,原型及实例之间的关系
1 | // 构造函数 |
如何让SubType继承SuperType?
1 | SubType.prototype // SubType {} |
初始时,SubType原型(SubType.prototype)指针指向function SubType(){…},SuperType原型(SuperType.prototype)指针指向function SuperType(){…}。
1 | SubType.prototype = new SuperType(); |
让原型(SubType.prototype)等于实例(new SuperType())
1 | SubType.prototype // SuperType {prop: true, getVal: function} |
该原型(SubType.prototype)就包含一个指向另一个原型的指针(SuperType.prototype),该原型(SubType.prototype)的指针也随即指向了SuperType.prototype的构造函数function SuperType(){…}。
并且SubType.prototype继承了SuperyType实例的所有属性和方法。
实例(instance)包含一个指向原型(SubType.prototype)的指针
1 | var instance = new SubType(); |
原型(SubType.prototype)的构造函数现在是function SuperType(){…},这样它的实例的构造函数也是function SuperType(){…}。
原型(SubType.prototype)中prop:true,但是function SubType(){this.prop=false;}中prop的值覆盖了原型上的值,所以 instance.getVal()返回false。
原型继承的问题
原型中所有属性是被实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性倒也说的过去,可以通过实例上添加同名属性,就可以隐藏原型中对应的属性。(比如上面的SubType中的prop)。
1 | function SuperType(){ |
正因为属性是被所有实例共享的,所以当使用引用属性时,就会影响所有实例。