close


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

原型 (Prototype)
這次的主題雖然不是 Prototype 本人,但和 Prototype 也有一點點關係,就快速從什麼是 Prototype 開始看吧!
對 JavaScript 有一定認識的人,一定都聽過 Prototype,所謂的原型 (Prototype) 是物件一個特殊屬性,它自己本身也是一個物件,每個物件都有自己的原型 (Prototype),內含一些方法及屬性,而我們平常使用的 toString(),也就是 Prototype 內的其中一個方法。

可以準備一個物件來看看,Prototype 到底是什麼。
【JavaScript 萌新筆記】JavaScript 的內
可以發現實際印出來的結果是 Object.prototype,而且顯示是一個空物件。
【JavaScript 萌新筆記】JavaScript 的內
再透過另一種方式建立物件,並把它的 Prototype 也印出來看看。
【JavaScript 萌新筆記】JavaScript 的內
可以發現一樣是一個空物件,但顯示上有點不太一樣。
【JavaScript 萌新筆記】JavaScript 的內
這裡印出來的其實是一個繼承 Person.prototype 的空物件。

從這個印出來的內容,我們可以再往下延伸的想個問題

- 什麼是 Object.prototype?
簡單來說就是一個物件最根源的的原型,所有物件都是繼承於這個原型,不管用什麼方式建立的物件都繼承 (inheritance) 於 Object.prototype,也就是說不論是哪個物件,都可以取用到 Object.prototype 內含的方法和屬性。

- 為什麼 Object.prototype 是一個空物件?
前面一直有提到 Object.prototype 內含有一些方法和屬性,但是印出來卻是空物件,這是怎麼一回事呢?

主要是因為 Object.prototype 這個所有物件繼承的 Prototype 的方法和屬性是隱性的,無法直接用 console.log 直接印出來。但還是可以透過其他方式把它印出來,例如可以透過 getOwnPropertyNames 把內部的方法和屬性印出來:
【JavaScript 萌新筆記】JavaScript 的內
【JavaScript 萌新筆記】JavaScript 的內


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

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


什麼是 Prototype Chain?
在用文字說明之前,我們先透過程式碼看一個情境。
【JavaScript 萌新筆記】JavaScript 的內
【JavaScript 萌新筆記】JavaScript 的內
第一個印出來的結果,毫無懸念一定是空物件,因為 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 進行理解的部分就到這裡告一個段落了,打完收工,寫些打家,打家百掰!
 

arrow
arrow

    文科少女寫程式 發表在 痞客邦 留言(0) 人氣()