1

继承是面向对象编程语言中的一个重要的概念,继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。但是在Javascript中没有的概念,是基于原型的语言,所以这就意味着对象可以直接从其他对象继承。

Ecmascript中描述了原型链的概念,并将原型链作为继承的主要方法,主要是想利用原型链让一个引用类型继承另一个引用类型的属性和方法。

构造函数、原型对象、实例之间的关系是:每个构造函数都有一个原型对象,每个原型对象中都有一个指针指向了该构造函数(constructor):

function A(){}
A.prototype.constructor == A //true

而实例中有一个内部的指针指向了原型对象([[prototype]]),在chrome,firefox等几款浏览器的JS引擎中加入了__proto__来访问原型对象[[prototype]]:

function B(){}
var b = new B();
b.__proto__ == B.prototype // true

当在实例对象中查找某一属性或方法的时候,会优先查找当前实例中是否包含该属性,如果未找到,便会在该实例的原型对象中查找,如果还未找到,就会再沿着原型对象中的内部原型指针继续往上层原型对象查找,层层递进,这样就构成了所谓的原型链。

function SuperType() {
  this.peoperty = 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的实例赋给SubType.prototype实现的,本质是重写了SubType的原型对象。

在Javascript中,所有引用类型都默认继承了Object,一样都是通过原型链来继承的。所以所有函数的默认原型都是Object.prototype,因此默认原型内部都会有一个指向Object.prototype的指针,所以上面的代码的原型链图形的顶层应该还有一个Object:


krew
1.3k 声望25 粉丝

脚踏实地