JavaScript使对象实例在内部持有这样一个__proto__属性,并且不允许用户访问。这样,用户可以出于任何目的来修改constructor属性,而不用担心实例与父类的一致性。——《JavaScript语言精粹与编程实践》
一、内部原型链
上一篇一步一步地看到了通过prototype属性和constructor属性如何形成JavaScript原型链。其实在这个原型链之外,正如本篇最开始引用的文字所描述的那样,因为prototype属性和constructor属性可以任意赋值,为了维系父类与实例之间的继承关系,JavaScript内部还有一个通过__proto__属性形成的内部原型链来保持各个对象之间的继承关系。
再贴一遍上篇中写的代码:
var Language = function (name) {
this.name = name;
};
Language.prototype.a ='aaa';
var lan1 = new Language('JavaScript');
考虑到每个对象的__proto__属性,上述代码在内部环境中的构成如下图所示:
图中虚线部分即内部原型链。以下是对上面图示的验证:
二、JavaScript原型链小结
最后加入了内部原型链的链图看上去有点“错综复杂”,一时看明白之后过个十天半月恐怕又会忘记。为了便于日后回忆,下面再对链图的特点做如下小结:
- 查找对象的某个属性的过程,就是遍历对象的原型链直到原型为空(null)或找到该属性的过程。
- 所有的对象最终都会引用(继承于)一个指向null的Object()构造器的实例。
- 函数也是一种对象,它继承于系统内置的Function()构造器的实例;函数的原型是系统内置的Object()构造器的实例。
- 构造器的原型的constructor属性总是指向构造器本身。