原型鏈,已經是一個老生常談的話題了,這裡就不過多總結,精華一張圖就可以搞定。該文章更多的是從 一個公式 的角度講述原型鏈。
補充說明
實例化:用類( class )創建對象( obj )的過程。如:
TensionMax = new Person() ,那麼 TensionMax 是 Persion 的實例(對象)。
但由於 JavaScript 並不存在類,所以 JavaScript 所謂的類,只是我們模擬出來的函數,最終還是基於原型構建。
以下 3 個觀點只是為了更方便快捷地理解原型鏈,切勿對號入座。其中依然存在著先有雞還是先有蛋的問題。對於單純的開發者來說,感興趣或者時間充裕的話可以深究,已附上友情鏈接於本章結尾。
先上結論
1、 obj.proto === class.prototype
滿足此式子時,我們可以把 obj 稱之為 class 實例出來的對象。
2、 obj 上屬性的查找會以 __proto__ 鏈條的方式進行查找,直到為 null 時終止。
3、以第 1 點為理解導向,原型鏈的終點是 Object.prototype 。
一、class.prototype === obj.__proto__
這條就當作是一個公式。滿足這一條,那麼我們可以把 obj 當作 class 實例出來的對象。
當我們實例出 Person 即 let Tension = new Person() :
let Person = function (name, age) {
this.name = name
this.age = age
this.race = 'human'
}
Person.prototype.country = 'China'
console.log(Person.prototype)
//輸出{country: 'China', constructor: Person}
也就是說 Person.prototype.constructor === Person
創建函數時,函數會自帶特有的屬性 prototype 。
而當實例 Persion 時
let TensionMax = new Person('huang', 10)
console.log(TensionMax) //{name: 'huang', age: 10, race: 'human'}
console.log(TensionMax.country) //China
console.log(TensionMax.__proto__.country) //China
換句話而言, new 操縱符 實際做了以下的事情。
let TensionMax = {} //即 new Object()
TensionMax.__proto__ = Person.prototype
Person.call(TensionMax)
//call在這裡的作用是將 Person 的 this 值拷貝到 TensionMax 對象中。
也就是說,當實例化對象後,對象 TensionMax 和對應的類 Person 通過 __proto__ 來鏈接。
二、obj 的屬性會以 "__proto__" 鏈條的方式進行查找,直到為 null 時終止
根據上述的關係圖,如果一直根據 __proto__ 這個鏈條查找,會有一個終點。
console.log(TensionMax.__proto__.__proto__.__proto__) //null
(TensionMax.__proto__).__proto__ === Object.prototype //true
根據第 1 點的公式, TensionMax.__proto__ 即 Person.prototype 為 Object 函數這個類實例出來的對象。最終到達終點 Object.prototype。
console.log(Object.prototype.prototype) //undefined
console.log(Object.prototype.__proto__) //null
三、原型鏈的終點是 Object.prototype
以第 1 點為理解導向,原型鏈的終點是 Object.prototype ,那麼有如下關係:
Tension為 Person 的實例對象;
Person為 Function 的實例對象;
Person.prototype 為 Object的實例對象;
Function為 Function 的實例對象;
Object為 Function 的實例對象;
Function.prototype為 Object 的實例對象。
根據第 1 點的公式,以 __proto__ 箭頭為導向可以看出,先有 Object.prototype ,由之誕生 Function.prototype ,隨後才有了 Function 和 Object 。
那麼 Function 和 Object 誰先有,還有待深究。