继承
其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。
首先了解下原型链
了解原型链之前先知道,每个实例对象(object)都有一个私有属性(称之为__proto__)指向它的原型对象(prototype),该原型对象也有一个自己的原型对象(为__proto__) ,层层向上直到一个对象的原型对象为 null
分析如下:
构造函数(Super) 有一个原型对象 prototype,
Super的原型对象prototype 包含一个指向构造函数的指针,
Super的实例(new Super())包含一个指向Super原型对象的内部指针
构造函数(Sub) 有一个原型对象 prototype,
Sub的原型对象prototype 包含一个指向构造函数的指针,
Sub的实例(new Sub()) 包含一个指向Sub原型对象的内部指针
现在,让Sub的原型对象prototype 等于Super 的实例(new Super())
Sub.prototype = new Super()
此时:本来Super的实例包含一个指向Super原型对象的内部指针,现在用Sub的原型替换Super的实例,得到Sub的原型对象 包含一个指向Super的原型对象的指针
Sub.prototype.__proto__ = Super.prototype
其中 让Sub的原型对象prototype 等于Super 的实例(new Super()) 就是所谓的继承
原型链是这样的:
ins_sb.__proto__ = Sub.prototype
Sub.prototype.__proto__ = Super.prototype
Super.prototype.__proto__ = Super
理解如下代码:
function SuperType() {
this.property = true
}
SuperType.prototype.getSuperValue = function () {
return this.property
}
function SubType() {
this.subproperty = false
}
// ⚠️注意
SubType.prototype = new SuperType()
SubType.prototype.getSubValue = function () {
return this.subproperty
}
var instance = new SubType()
console.log(instance.getSuperValue()) // true
在上述代码中,我们没有使用SubType默认提供的原型,而是给它换了一个新原型,这个新原型就是SuperType的实例。
于是,新原型不仅具有作为一个SuperType的实例所拥有的全部属性和方法,而且其内部还有一个指针,指向SuperType的原型,SubType的原型又指向SuperTYpe的原型。
其结果就是:instance指向SubType的原型,SubType的原型又指向SuperType的原型。这就是原型链~
好了,再理一下为何getSuperValue()方法在SuperType.prototype中,但是property则位于SubType.property中?
这是因为property是实例属性,而getSuperValue则是一个原型方法。既然SubType.property现在是SuperType的实例,那property 就当然位于SubType.property中了