只看一次絕對學不會的 JavaScript 原型指南(一):初探原型、原型繼承與原型鏈
相信許多初次接觸 JavaScript 原型的人都跟我有過同樣的經歷,在開始深入學習之前就被一連串相似的術語名詞弄得暈頭轉向,如「proto」、「prototype」、「[[Prototype]]」、「原型 (prototype)」、「原型鏈 (prototype chain)」、「原型繼承 (prototypal inheritance)」等。這些術語表面上相似,但實際上指涉的概念卻不相同,很容易混淆,即便我已經接觸 JavaScript 好一段時間了,要理解這些原型相關的知識還是花了我不少時間。
雖然在日常開發中,我們幾乎不會直接操作到物件的原型,但我認為,若想對 JavaScript 這個語言有更深層的 理解,花一點時間學習原型仍然是非常重要且值得的。原型繼承雖然是一個抽象的概念,但卻是這門語言物件導向程式設計的核心基石。透徹理解原型,將為我們開啟對 JavaScript 更深層且宏觀的視野。由於原型涵蓋的概念與知識量很多,為了方便閱讀,我將會我對原型的理解拆成幾篇文章來介紹。本篇文章將會先簡單介紹原型(Prototype) 、原型鏈(Prototype chain) 與原型繼承(Prototypal inheritance) 的概念。本篇文章將帶領讀者先一步步認識 JS 原型中常見的名詞,以及最基本的概念,希望能夠幫助讀者建立起對 JS 原型的基礎認識。
原型 (Prototype)
JavaScript 中的原型(prototype)是什麼?
在 JavaScript 中,每個物件都有一個隱藏屬性 [[Prototype]],這個屬性指向另一個物件,這個被指向的物件稱為該物件的「原型」。原型的作用是讓物件可以繼承其他物件的屬性和方法,這是一種實現繼承的方式。
由於 [[Prototype]] 為內部屬性並無法直接被訪問到,JavaScript 提供了一個方便的屬性: __proto__ ,來存取和修改物件的原型。__proto__ 是一個非標準但被大多數現代瀏覽器支持的屬性,用於讀取和設置物件的原型。
例如:
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal;
console.log(rabbit.eats); // true,從 animal 繼承
console.log(rabbit.jumps); // true,rabbit 自己的屬性
在這個例子中,我們使用 __proto__ 來設置 rabbit 的原型為 animal,從而使 rabbit 繼承了 animal 的屬性。