記得有一次面試, 就考到了原型鏈. 面試官在批改個人筆試題時, 他忽然說你這題是作對了, 那你把它完整的原型鏈畫出來吧! 難受😣, 當時我也是隻知其一;不知其二的作對了, 我只能瞎操做一頓了.javascript
今天就好好整理下關於原型鏈
的知識vue
要理解原型鏈是什麼, 就要知道什麼是__proto__、什麼是prototype、還有constrtctor, 以及他們之間的關係java
一、__proto__
js的Function其實就是一個對象, 那js中的對象有個一特殊[[prototype]]
內置屬性, 幾乎搜索對象在建立時候 [[prototype]]
都會賦予一個非空的值. 注: [[prototype]]
也就是 __proto__
, 一些書籍上就標記爲[[prototype]], 瀏覽器中爲__proto__
. 常說的原型鏈條就是 [[prototype]]鏈
或者 __proto__鏈
.面試
二、prototype瀏覽器
每一個Function
都會有一個prototype屬性, 叫作原型.函數
三、constructorpost
構造函數的prototype
屬性的constructor
屬性指向其自己(如構造函數Foo, 它的原型上的construstor
(即Foo.prototype.construstor === Foo
)指向它自己; 實例的constructor
指向構造函數自己(即foo.constructor === Foo
)ui
先來一個圖熱身spa
是否是常常在網上看到一個相似這樣的關係圖, 各類箭頭指來指去的, 感受好難.prototype
其實, 還有更難的
上圖你能夠先忽略其餘的, 先看原型鏈部分
你能夠將箭頭理解爲一個指向或者理解爲它是一個等號, 那就很容易總結出一個規律了. 寫了一個構造函數Foo
, 實例化出來一個foo
, foo
上就會有一個__proto__
屬性, 指向它的構造函數爸爸
的原型Foo.prototype
, Foo.prototype
上又有一個__proto__
, 指向Foo的爸爸
Object的原型上Object.prototype
, 可憐的是Object已經沒有爸爸
了, 最終Object.prototype.__proto__
指向null
, 原型鏈尋找屬性的過程到了null就結束了
簡單一點總結就是: 兒子(foo)
的__proto__
指向 爸爸(Foo)
的prototype
, 爸爸的prototype.__proto__
指向爺爺(Object)
的 prototype
, ... 最終指向到null結束
最終出現只樣的調用鏈
foo.__proto__ === Foo.prototype // true
Foo.prototype.__proto__ === Object.prototype // true
Object.prototype.__proto__ === null // true
// 根據上面的關係, 可以得出如下鏈式
foo.__proto__.__proto__.__proto__ === null // true
複製代碼
當咱們去調用一個foo
沒有的屬性時候, 它會沿着這條鏈往上去尋找, 找到爲止或者找到null
才中止
// 構造函數
function Foo () {
console.log('Foo構造函數')
}
// foo實例
const foo = new Foo()
console.log('一、',foo.__proto__ === Foo.prototype) // true
console.log('二、', Foo.prototype.constructor === Foo) // true
console.log('三、', Foo.prototype.__proto__ === Object.prototype) // true
console.log('四、', Object.prototype.__proto__ === null) // true
console.log('五、', foo.__proto__.__proto__.__proto__ === null) // true
console.log('六、', foo.constructor === Foo.prototype.constructor) // true
console.log('七、', foo.constructor === foo.__proto__.constructor) // true
console.log('八、', foo.constructor === Foo) // true
console.log('九、', Foo.constructor === Object.constructor) // true
console.log('十、', Foo.__proto__ === Function.prototype) // true
console.log('十一、', Function.prototype.__proto__ === Object.prototype) // true
console.log('十二、', Function.__proto__ === Function.prototype) // true
console.log('1三、', Function.constructor === Function) // true
console.log('1四、', Object.constructor === Function) // true
console.log('1五、', Foo.constructor === Function) // true
console.log('1六、', Object.__proto__ === Function.prototype) // true
複製代碼
其餘文章: