JS STUDY NODE

Javascript Prototype Chain

Azole (小賴)
Dec 13, 2020

整理一下 Javascript prototype chain。

最近要講課,在想要怎麼解釋 javascript prototype chain,沒想到翻到自己以前的文章(https://imazole.wordpress.com/2013/12/23/javascript-prototype-chain/),原來我自己以前這麼好的領悟過,趕快搬過來 medium 這裡再做一次紀錄。

其實這也不是我自己整理的,而是來自這篇文章 JavaScript對象與原型,但一直到某一天心血來潮地把線上色後,才突然有一種恍然大悟的感覺:

借由這個圖可以看到,prototype chain 的關鍵其實是在 __proto__ 上(藍線):

  1. foo 是一個 Foo 的 object,所以其 __proto__ 是指向 Foo.prototype。
  2. 同1. obj 是一種 Object 物件,所以其 __proto__ 是指向 Object.prototype。
  3. Foo 本身是一個 Foo 物件的建構子,建構子是一種特殊的「函式」,所以其 __proto__ 是指向 Function.prototype。
  4. 同3. Function 跟 Object 都是一種建構子,所以其 __proto__ 是指向 Function.prototype。
  5. Foo.prototype 是一種物件,所以其 __proto__ 指向 Object.prototype。
  6. 同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 的工具,但最好不要使用與修改。

參考資料:

--

--

Azole (小賴)

As a passionate software engineer and dedicated technical instructor, I have a particular fondness for container technologies and AWS.