理解javascript的原型链
一直不理解javascript的原型链,在网上查了不少资料,终于找到一张个人认为能很好地理解的javascript原型图,在这里记录一下,javascript原型图如下:
根据图上所示,可以看出:
1)javascript有__proto__和prototype两个属性(__proto__为内置属性,一般访问不到,firefox可以访问),而整个javascript的原型链是通过__proto__属性连接起来的,prototype属性只是为了辅助原型链的建立;
2)原型链最终指向Object的__proto__为null,可以在firefox中得到验证;
3)由于Object本身又是function,所以Object的__proto__会先指向Function,然后再由Function指向Object,有种鸡和蛋的感觉,怪不得容易混淆;
4)对于实例来说,即var o = new XXX(),其原型链类似:
o.__proto__ ==> XXX.prototype(多级也类似)==> Object.prototype ==> null;
5)对于构造函数,其原型链都是先经过Function.prototype,再指向Object;
6)从图中可以看出,prototype、constructor、构造函数间的关系为:函数体本身==> prototype ==> constructor ==> 函数体本身,可以理解为一个环(在firefox中可以很容易看出来),这可能也是需要有隐式的__proto__属性的原因,因为prototype是一个无限循环,所以在属性或方法遍历的时候用的是__proto__属性。
另外,在创建实例时__proto__链是通过New关键字完成的,New分以下3步(以var o = new X()为例):
1)var F = {};// 创建一个空对象
2)F.__proto__ = X.prototype;// 将空对象的原型指向构造函数的原型
3)X.call(F);// 执行函数体
通过1)2)两步将实例与构造函数原型连接起来的。