【JavaScript 萌新筆記】JavaScript 的內部插槽 (internal slots) 和內部方法 (internal methods)

文科少女學程式
13 min readApr 28, 2024

這幾天在看一些之前沒有認真研究過的東西,突然看到了 internal slots 這個詞彙,小女我真的很不才,這是我第一次看到這個詞,就先拋棄自己原本在看的東西,轉向看看什麼是 internal slots 了,這次就來整理一下自己查了一些資料後,對於 internal slots 的理解。這次會先從 object 的 Prototype 開始了解,再進一次回到這次的主題「內部插槽 (internal slots) 和內部方法 (internal methods)」。

原型 (Prototype)

這次的主題雖然不是 Prototype 本人,但和 Prototype 也有一點點關係,就快速從什麼是 Prototype 開始看吧!
對 JavaScript 有一定認識的人,一定都聽過 Prototype。所謂的原型 (Prototype) !

是物件一個特殊屬性,它自己本身也是一個物件,每個物件都有自己的原型 (Prototype),內含一些方法及屬性。

而我們平常使用的 toString(),也就是 Prototype 內的其中一個方法。

可以準備一個物件來看看,Prototype 到底是什麼。


可以發現實際印出來的結果是 Object.prototype,而且顯示是一個空物件。


再透過另一種方式建立物件,並把它的 Prototype 也印出來看看。


可以發現一樣是一個空物件,但顯示上有點不太一樣。


這裡印出來的其實是一個繼承 Person.prototype 的空物件。

從這個印出來的內容,我們可以再往下延伸的想個問題
- 什麼是 Object.prototype?
簡單來說就是一個物件最根源的的原型,所有物件都是繼承於這個原型,不管用什麼方式建立的物件都繼承 (inheritance) 於 Object.prototype,也就是說不論是哪個物件,都可以取用到 Object.prototype 內含的方法和屬性。

- 為什麼 Object.prototype 是一個空物件?
前面一直有提到 Object.prototype 內含有一些方法和屬性,但是印出來卻是空物件,這是怎麼一回事呢?主要是因為 Object.prototype 這個所有物件繼承的 Prototype 的方法和屬性是隱性的,無法直接用 console.log 直接印出來。但還是可以透過其他方式把它印出來,例如可以透過 getOwnPropertyNames 把內部的方法和屬性印出來:

- 什麼是 Person.prototype?跟 Object.prototype 的差異是?
了解完什麼是 Object.prototype 後,也進一步看一下前面的第二種創建 object 方法中所提到的 Person.prototype 是什麼。

當我們創建一個名為 Person 的 function 時,這個函式會自動擁有一個名為 Prototype 屬性,這個 Prototype 會指向一個空物件,我們會把這個空物件稱為 Person.prototype,這個空物件是繼承於物件的基底 Prototype,也就是Object.prototype。當我們透過 new Person() 產生一個物件時,這個物件也就會繼承於 Person.prototype。

什麼是 Prototype Chain?

在用文字說明之前,我們先透過程式碼看一個情境。


第一個印出來的結果,毫無懸念一定是空物件,因為 function 內是空的,沒有另外透過 this 去增加屬性。但是第二個 console.log 印出來的結果,居然不是 undefined!這是怎麼回事呢?

這就是因為 JavaScript 一個很重要的特性,也就是所謂的「Prototype Chain ( 原型鏈 )」。 這是 JavaScript 中實現繼承的主要機制之一,在 JavaScript 中幾乎所有的物件都會透過原型鏈相互關聯。

如同前面有說過的「每個物件都有自己的原型 (prototype)」,當取用一些方法或是屬性時,如果在當前的這個物件中找不到,就會繼續往這個物件繼承的那一層找,所以也就會往Prototype找,剛好 ValueOf 是存在於 Prototype 中的方法,印出來也就不是 undefined。

什麼是內部插槽 (internal slots) 和內部方法 (internal methods)?

前面說了那麼多prototype,終於要來看看今天的主角了。

(internal slote) 和 (internal methods) 是 JavaScript 語言規範中的概念,是用來描述物件的內部結構和行為。但是這些內部插槽和方法通常不會被直接訪問或修改,而是由 JavaScript 引擎用於實現物件的行為和特性。

簡單來說的話,就是一個像是用來當作JavaScript 的屬性和方法的標籤,你不會直接拿這個標籤來使用,但你可以知道裡面含有這些屬性和方法。

通常會使用 [[]]的方法來表示 internal slots 或 internal methods,例如:[[Prototype]]。

內部插槽 (internal slots) 和內部方法 (internal methods) 與 Prototype 的關係是?

前面大致上了解什麼是 internal slots 和 internal methods之後,讓我們再回頭結合前面提到過的 Prototype 來思考一下和 prototype 之間的關係是什麼吧!

就如同前面所提到的一樣,可以把internal slots 和 internal methods 想像成是一個標籤,所以 [[Prototype]] 就代表著標示著 JavaScript 有著這一個屬性,並且指向物件的原型,但是 [[Prototype]] 不等同於 Prototype,[[Prototype]] 是一個內部屬性,而我們一開始提到的 Prototype則是內含共用屬性及方法的物件。

總結

最後快速總結一下這次的幾個重點!
- internal slots 和 internal methods 是內部屬性,會指向一個特定的物件,通常不會被直接使用,它們也像是一個標籤,標示著JavaScript有哪些屬性和方法。
- Prototype 是一個物件,每個物件都有自己所繼承的 Prototype 物件,內含一些共用的方法和屬性。
- [[Prototype]] 這個 internal slots 和 Prototype是不同的東西,[[Prototype]] 是一個 internal slots,Prototype則是一個物件。

這次針對 Prototype 和 internal slots 進行理解的部分就到這裡告一個段落了,打完收工,寫些打家,打家百掰!

這幾天在看一些之前沒有認真研究過的東西,突然看到了 internal slots 這個詞彙,小女我真的很不才,這是我第一次看到這個詞,就先拋棄自己原本在看的東西,轉向看看什麼是 internal slots 了,這次就來整理一下自己查了一些資料後,對於 internal slots 的理解。這次會先從 object 的 Prototype 開始了解,再進一次回到這次的主題「內部插槽 (internal slots) 和內部方法 (internal methods)」。

原型 (Prototype)

這次的主題雖然不是 Prototype 本人,但和 Prototype 也有一點點關係,就快速從什麼是 Prototype 開始看吧!
對 JavaScript 有一定認識的人,一定都聽過 Prototype。所謂的原型 (Prototype) !

是物件一個特殊屬性,它自己本身也是一個物件,每個物件都有自己的原型 (Prototype),內含一些方法及屬性。

而我們平常使用的 toString(),也就是 Prototype 內的其中一個方法。

可以準備一個物件來看看,Prototype 到底是什麼。


可以發現實際印出來的結果是 Object.prototype,而且顯示是一個空物件。


再透過另一種方式建立物件,並把它的 Prototype 也印出來看看。


可以發現一樣是一個空物件,但顯示上有點不太一樣。


這裡印出來的其實是一個繼承 Person.prototype 的空物件。

從這個印出來的內容,我們可以再往下延伸的想個問題
- 什麼是 Object.prototype?
簡單來說就是一個物件最根源的的原型,所有物件都是繼承於這個原型,不管用什麼方式建立的物件都繼承 (inheritance) 於 Object.prototype,也就是說不論是哪個物件,都可以取用到 Object.prototype 內含的方法和屬性。

- 為什麼 Object.prototype 是一個空物件?
前面一直有提到 Object.prototype 內含有一些方法和屬性,但是印出來卻是空物件,這是怎麼一回事呢?主要是因為 Object.prototype 這個所有物件繼承的 Prototype 的方法和屬性是隱性的,無法直接用 console.log 直接印出來。但還是可以透過其他方式把它印出來,例如可以透過 getOwnPropertyNames 把內部的方法和屬性印出來:

- 什麼是 Person.prototype?跟 Object.prototype 的差異是?
了解完什麼是 Object.prototype 後,也進一步看一下前面的第二種創建 object 方法中所提到的 Person.prototype 是什麼。

當我們創建一個名為 Person 的 function 時,這個函式會自動擁有一個名為 Prototype 屬性,這個 Prototype 會指向一個空物件,我們會把這個空物件稱為 Person.prototype,這個空物件是繼承於物件的基底 Prototype,也就是Object.prototype。當我們透過 new Person() 產生一個物件時,這個物件也就會繼承於 Person.prototype。

什麼是 Prototype Chain?

在用文字說明之前,我們先透過程式碼看一個情境。


第一個印出來的結果,毫無懸念一定是空物件,因為 function 內是空的,沒有另外透過 this 去增加屬性。但是第二個 console.log 印出來的結果,居然不是 undefined!這是怎麼回事呢?

這就是因為 JavaScript 一個很重要的特性,也就是所謂的「Prototype Chain ( 原型鏈 )」。 這是 JavaScript 中實現繼承的主要機制之一,在 JavaScript 中幾乎所有的物件都會透過原型鏈相互關聯。

如同前面有說過的「每個物件都有自己的原型 (prototype)」,當取用一些方法或是屬性時,如果在當前的這個物件中找不到,就會繼續往這個物件繼承的那一層找,所以也就會往Prototype找,剛好 ValueOf 是存在於 Prototype 中的方法,印出來也就不是 undefined。

什麼是內部插槽 (internal slots) 和內部方法 (internal methods)?

前面說了那麼多prototype,終於要來看看今天的主角了。

(internal slote) 和 (internal methods) 是 JavaScript 語言規範中的概念,是用來描述物件的內部結構和行為。但是這些內部插槽和方法通常不會被直接訪問或修改,而是由 JavaScript 引擎用於實現物件的行為和特性。

簡單來說的話,就是一個像是用來當作JavaScript 的屬性和方法的標籤,你不會直接拿這個標籤來使用,但你可以知道裡面含有這些屬性和方法。

通常會使用 [[]]的方法來表示 internal slots 或 internal methods,例如:[[Prototype]]。

內部插槽 (internal slots) 和內部方法 (internal methods) 與 Prototype 的關係是?

前面大致上了解什麼是 internal slots 和 internal methods之後,讓我們再回頭結合前面提到過的 Prototype 來思考一下和 prototype 之間的關係是什麼吧!

就如同前面所提到的一樣,可以把internal slots 和 internal methods 想像成是一個標籤,所以 [[Prototype]] 就代表著標示著 JavaScript 有著這一個屬性,並且指向物件的原型,但是 [[Prototype]] 不等同於 Prototype,[[Prototype]] 是一個內部屬性,而我們一開始提到的 Prototype則是內含共用屬性及方法的物件。

總結

最後快速總結一下這次的幾個重點!
- internal slots 和 internal methods 是內部屬性,會指向一個特定的物件,通常不會被直接使用,它們也像是一個標籤,標示著JavaScript有哪些屬性和方法。
- Prototype 是一個物件,每個物件都有自己所繼承的 Prototype 物件,內含一些共用的方法和屬性。
- [[Prototype]] 這個 internal slots 和 Prototype是不同的東西,[[Prototype]] 是一個 internal slots,Prototype則是一個物件。

這次針對 Prototype 和 internal slots 進行理解的部分就到這裡告一個段落了,打完收工,寫些打家,打家百掰!

--

--

文科少女學程式

一名畢業於韓文系的少女,因為想挑戰自我,而踏上程式語言的學習之路,最後不小心成為前端工程師,進入了更深的前端學習世界。