prototype chain
為什麼會說再呢?
之前有照著老師的文章也寫了兩篇,但是內容跟老師的有 87% 一樣,只是練習一下寫文章的感覺而已。
這次再稍微深入一點點(真的只有一點點),做了些筆記。
prototype
- 只有 function 才有
prototype屬性 - 當創建一個 function,JavaScript 會自動幫這個 function 添加
prototype屬性,值是一個有 constructor 的物件(註一) - 當這個 function 被當作建構函數(constructor)調用(就是用 new 來調用),JavaScript 會創建該 constructor 的實例(instance)
- 這個 instance 會繼承 constructor 的
prototype裡所有屬性跟方法(透過 instance 的__proto__指向 constructor 的prototype) A instanceof B就是從 A 的__proto__.proto__...去找 B 的prototype- 所以原型鏈其實是一連串的
__proto__
註一:function 的 prototype 的 constructor 就是 function 自己本身。
__proto__
JavaScript 每個東西(?)都有 __proto__ 來標示自己繼承的原型。
const obj = {}
const num = 123
const str = '666'
console.log(obj.__proto__ === Object.prototype) // true
console.log(num.__proto__ === Number.prototype) // true
console.log(str.__proto__ === String.prototype) // true
new
其實當我們 new 了一個新的 instance 時,會發生以下幾件事:
- 建立一個空白的 JavaScript 物件
- 新增
__proto__屬性到該新物件,這個屬性會指向建構函式的prototype物件 - 把 this 綁定到該新物件,也就是建構函式中的 this 會指向該新物件
- 如果函式沒有 return 任何東西,就會 return this
名詞釐清
- prototype:本質應該就是個一般物件而已(?)
- Object
- 一般物件:Object literal,就是我們一般在 code 會用
{}包起來然後在裡面放東西的那個物件,他的原型是Object.prototype - 構造函數 Object:原型為
Function.prototype,剛好有個東西叫做Object.prototype,但其實Object.prototype比這個構造函數 Object 還要早出現
- 一般物件:Object literal,就是我們一般在 code 會用
- Function
- 一般函式:構造函數 Function 的實例,所以原型是
Function.prototype - 構造函數 Function:原型為
Function.prototype
- 一般函式:構造函數 Function 的實例,所以原型是
Function.prototype:所有構造函數的原型,也就是所有構造函數的__proto__皆指向Function.prototypeObject.prototype:原型鏈的頂端,prototype 的王者Object.prototype跟Function.prototype是獨立於Object跟Function特別的存在,要把他們抽出來看
再來看一張圖,可以幫助釐清這些東西
圖片來源:理解JavaScript的原型链和继承 (oyanglul.us)
從這張圖來看就簡單多了,可以分成兩大類:
__proto__指向Function.prototype的(建構)函式們__proto__指向Object.prototype的物件們
Function 跟 Object 互為 instance
console.log(Function instanceof Object) // true
console.log(Object instanceof Function) // true
如果你知道 instanceof 的機制,而且了解了上面那些關係,那這個雞生蛋蛋生雞的問題就很簡單了。
A instanceof B 就是到 A 的 __proto__... 找 B.prototype 而已
- Function instanceof Object
Function.__proto__ === Function.prototypeFunction.prototype.__proto__ === Object.prototype- 所以
Function.__proto__.__proto__ === Object.prototype
- Object instanceof Function
Object.__proto__ === Function.prototype
從分類來看
prototype
只有尊爵不凡的函式才有
- Object.prototype
- prototype 的王者,所有 prototype 的
__proto__都會指向Object.prototype
- prototype 的王者,所有 prototype 的
- Function.prototype
- 所有(建構)函式的
__proto__都會指向Function.prototype
- 所有(建構)函式的
- 其他(建構)函式的 prototype
- 單純的 JavaScript 物件(?),以
Function.prototype為原型
- 單純的 JavaScript 物件(?),以
建構函式
- JavaScript 原有的建構函式
Function、Object、Array、String…等。
- 自定義的建構函式
- 自己寫一個 function 當作 constructor,你懂的。
總結
Object.prototype -> Function.prototype -> Function、Object、String 等其他建構函式


