寫在前面
說到原型鏈這個愛恨交織、錯綜複雜的東西,今天我們就來看看這是個神馬東東
首先追本溯源,爲啥有原型鏈這麼個東西,這就要講到原型,繼承,對象這些概念
1. 對象
對象 object 說到對象的概念,我們都會仰天長嘆:萬物皆對象;
在不同的編程語言中,設計者也利用各種不同的語言特性來抽象描述對象,最爲成功的流派是使用“類”的方式來描述對象,這誕生了諸如 C++、Java 等流行的編程語言,
然而 JavaScript 爲了保證對象之間的聯繫,引入了原型與原型鏈的概念
2. 原型(prototype)與原型鏈
如果說js是基於對象的,那麼它也是基於原型的,現在我們先來理解幾個點:
- 對象和函數可以說是相輔相成,對象都是函數創建出來的
你會不會擡槓的問:
var a = {name: 'nihao'}
那你知道不,其實這段代碼是這樣的:
var a = new Onject()
a.name = 'nihao'
你看還是函數創建出來的
- 函數也是一個對象,不信你看函數也是一個對象,不信你看
var fn = function(){}
fn instanceof Object // true
- 每個實例對象(object )都有一個私有屬性__proto__
- 每個函數都有一個 prototype 屬性
- 對象的私有屬性__proto__指向它的原型對象prototype,該原型對象也有一個自己的原型對象__proto__
- 只有原型對象纔有constructor屬性,constructor屬性其實是一個Object,指向同名的構造函數
- 依次層層向上搜索,直到找到一個名字匹配的屬性或到達原型鏈的末尾,即直到一個對象的原型對象爲 null,根據定義,null 沒有原型,並作爲這個原型鏈中的最後一個環節。
根據這幾個點,我們通過幾張圖來簡單理解一下
再來一層
當把函數也看做一個對象的時候,對象就有__proto__屬性,圖形就更復雜了