當我們調用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