JS STUDY NODE
Javascript Prototype Chain
整理一下 Javascript prototype chain。
最近要講課,在想要怎麼解釋 javascript prototype chain,沒想到翻到自己以前的文章(https://imazole.wordpress.com/2013/12/23/javascript-prototype-chain/),原來我自己以前這麼好的領悟過,趕快搬過來 medium 這裡再做一次紀錄。
其實這也不是我自己整理的,而是來自這篇文章 JavaScript對象與原型,但一直到某一天心血來潮地把線上色後,才突然有一種恍然大悟的感覺:
借由這個圖可以看到,prototype chain 的關鍵其實是在 __proto__ 上(藍線):
- foo 是一個 Foo 的 object,所以其 __proto__ 是指向 Foo.prototype。
- 同1. obj 是一種 Object 物件,所以其 __proto__ 是指向 Object.prototype。
- Foo 本身是一個 Foo 物件的建構子,建構子是一種特殊的「函式」,所以其 __proto__ 是指向 Function.prototype。
- 同3. Function 跟 Object 都是一種建構子,所以其 __proto__ 是指向 Function.prototype。
- Foo.prototype 是一種物件,所以其 __proto__ 指向 Object.prototype。
- 同5. Function.prototype 是一種物件,所以 __proto__ 是指向 Object.prototype。
由此也可以看出,javascript 的 prototype chain 的最高層是 Object.prototype。
其實會有 __proto__
這個屬性是因為 JS 原本是不提供直接存取物件的 prototype 的,但大部分的 JS 引擎提供了 __proto__
這個屬性來讓我們可以取得物件的 prototype。而從 ES5 後,就可以透過 Object.getPrototypeOf()
這個方法來取得。
var foo = new Foo();
以這行程式來說,其實是做了以下這些事:
var foo = {}; // 製作一個空物件
foo.__proto__ = Foo.prototype; // 把這個空物件的 __proto__ 指向 Foo.prototype
Foo.call(foo); // 把 Foo 中的 this 指定為 foo 這個物件
這邊要特別留意的是,__proto__
是一個用來取得物件的原型的非標準機制,在這邊可用來當做理解 prototype chain 的工具,但最好不要使用與修改。
參考資料:
- Effective Javascript Chapter 4 物件和原型
- JavaScript對象與原型