当我们调用Bar.prototype = Object.create(Foo.prototype)
,不应Bar.prototype
现在引用新的对象,是Foo.prototype
副本...
Object.create
不复制对象。它创建了一个新的对象,其原型underyling是我们传递所以用这个首发:
+---------------+
| Foo.prototype |
+---------------+ +----------------------+
| [[Prototype]] |---->| Object.prototype |
+---------------+ +----------------------+
| identify: ... | | [[Prototype]]: null |
+---------------+ +----------------------+
| ... |
+----------------------+
(我已经离开了函数对象为identify
为简单起见。)
...当我们这样做Bar.prototype = Object.create(Foo.prototype)
,它创建了一个:
+---------------+
| Bar.prototype |
+---------------+ +---------------+
| [[Prototype]] |---->| Foo.prototype |
+---------------+ +---------------+ +----------------------+
| [[Prototype]] |---->| Object.prototype |
+---------------+ +----------------------+
| identify: ... | | [[Prototype]]: null |
+---------------+ +----------------------+
| ... |
+----------------------+
后来,执行Bar.prototype.speak = function...
行之后,Bar.prototype
也有speak
财产。
+---------------+
| Bar.prototype |
+---------------+ +---------------+
| [[Prototype]] |---->| Foo.prototype |
+---------------+ +---------------+ +----------------------+
| speak: ... | | [[Prototype]] |---->| Object.prototype |
+---------------+ +---------------+ +----------------------+
| identify: ... | | [[Prototype]]: null |
+---------------+ +----------------------+
| ... |
+----------------------+
var b1 = new Bar("b1");
后,我们有:
+---------------+
| b1 |
+---------------+ +---------------+
| [[Prototype]] |---->| Bar.prototype |
+---------------+ +---------------+ +---------------+
| me: "b1" | | [[Prototype]] |---->| Foo.prototype |
+---------------+ +---------------+ +---------------+ +----------------------+
| speak: ... | | [[Prototype]] |---->| Object.prototype |
+---------------+ +---------------+ +----------------------+
| identify: ... | | [[Prototype]]: null |
+---------------+ +----------------------+
| ... |
+----------------------+
[在上面,[[Prototype]]
指对象的内置链接到它的原型;名称为[[Prototype]]
的对象上没有真正的属性。 事实上,在ES5中,没有办法从对象本身直接访问原型的链接,尽管ES5增加了Object.getPrototypeOf
,它可以让你通过传入对象引用来检索它,例如, var p = Object.getPrototypeOf(someObject)
。 ES6将添加更多方式与对象的原型进行交互,包括Mozilla的JavaScript多年以来的__proto__
属性。]
这很有道理,谢谢!只是为了澄清我最后一个问题。在该Bar.prototype上,它有__proto__,它是Prototype链接的公共版本,那么它也会有说法? – HelloWorld 2014-09-28 17:04:28
@HelloWorld:是的,稍后,我们添加它。不是在Object.create之后。我应该证明这一点。 – 2014-09-28 17:06:49
很好的解释,非常感谢@ T.J Crowder! – HelloWorld 2014-09-28 17:08:02