JavaScript 的 原型
JavaScript 物件原型。
同步發表於 HackMD:原型
詳細筆記在 HackMD,這裡就貼總結就好了。
總結
1. [[Prototype]]
JavaScript 中的每個物件具有個特殊的隱藏屬性,在規範中以 [[Prototype]]
命名表示。
[[Prototype]]
的值會是另一個物件的參考或是 null
。
這個物件的參考,會稱為「原型」或是「原型物件」。
原型物件也有自己的原型物件,原型物件的原型物件也有自己的原型物件,而這一長串鏈會稱為「原型鏈」。
當物件進行屬性存取的動作時,會先檢視該物件是否有屬性可以呼叫,如果沒有,會順著該物件的 [[Prototype]]
連結往上層尋找。
原型鏈的最頂層為 Object.prototype
,它的 [[Prototype]]
值會是 null
。
2. __proto__
屬性
在 ES5 之前,沒有標準的方法可以訪問這個 [[Prototype]]
。只能透過瀏覽器為物件提供的 __proto__
屬性來訪問。
直到 ES5,才有了 Object.getPrototypeOf()
可以查看 [[Prototype]]
。到了 ES6 才有 Object.setPrototypeOf()
可以設定它。
而__proto__
屬性,直到 ES6 為了確保瀏覽器相容才被標準化,
3. [[Prototype]]
預設值
物件、陣列、函式 [[Prototype]]
預設值:
let obj = {};
console.log(obj.__proto__); // Object.prototype
console.log(obj.__proto__.__proto__); // null
let arr = [];
console.log(arr.__proto__); // Array.prototype
console.log(arr.__proto__.__proto__); // Object.prototype
function fun() {}
console.log(fun.__proto__); // Function.prototype
console.log(fun.__proto__.__proto__); // Object.prototype
最終都會指向 Object.prototype
3. Object.create()
ES5 新增的 Object.create()
,能建立出一個物件,該物件的 [[Prototype]]
會是輸入的第一個參數。
4. prototype
屬性
每個函式都有 prototype
屬性,它會指向一個物件,該物件有 constructor
屬性會指向原函式。
當函式以建構式呼叫,建立出來的實體物件的 [[Prototype]]
會指向建構函式的 prototype
屬性指向的物件。
5. [[Prototype]]
的指向
設定物件的 [[Prototype]]
有三種方式:
__proto__
屬性或Object.setPrototypeOf()
- ES5 新增的
Object.create()
- 建構函式的
prototype
屬性
直接設定物件的 [[Prototype]]
值是緩慢的動作、效能低,而且程式碼難以維護,應該盡量避免這樣的操作。
如果函式的 prototype
屬性,不是預設的物件有重新指派,那裏面將不會有 constructor
屬性,必須手動設置。