代碼
講解用到的代碼很簡單,如下
function Foo(){
//屬性和方法
}
var f1 = new Foo();
var f2 = new Foo();
var o1 = new Object();
var o2 = new Object();
基礎了解
一切皆對象,對象又可以分為兩類:
- 普通對象 蛛淋,除了函數(shù)對象之外的對象都是,包括new函數(shù)對象()產(chǎn)生的實例篡腌,普通對象沒有prototype褐荷,也就沒有繼承和原型鏈一說。
- 函數(shù)對象 嘹悼,包括兩種:
-
由function創(chuàng)造出來的函數(shù):
function f1() { } // 匿名函數(shù) var f2 = function() { } var f3 = new Function('x','console.log(x)'); // 以上都是函數(shù)對象
系統(tǒng)內置的函數(shù)對象:
Function叛甫、Object、Array杨伙、String其监、Number ,Function其實充當了函數(shù)對象的構造器限匣,比如Object對象的構造源碼其實是Function Object() {[native code]}的形式抖苦,這一點對于理解原型鏈很重要。
進入正題
上圖從結構上分為實例對象米死、Functions函數(shù)對象锌历、prototype原型對象三部分,圖中f1峦筒、f2的原型鏈我特意標成了紅色究西,F(xiàn)oo的原型鏈為紫色。
每個對象都有__proto__
屬性物喷,用于儲存繼承得來的方法和屬性卤材;每個函數(shù)對象都有prototype
屬性,用于繼承峦失,將其中定義的屬性和方法傳遞給‘后代’(比如實例化)坯认。
如何實現(xiàn)原型繼承
f1為何有Foo昔善、Object的原型方法骂蓖,其實就是通過原型鏈繼承萝风。繼承的過程可以表示為f1.__proto__ = Foo.prototype
,即對象.__proto__ = 構造器.prototype
。
new實例實現(xiàn)繼承的過程其實與上面原理相同实幕,new的過程可以拆解為下面幾個步驟:
var temp = {};
temp.__proto__ = Foo.prototype; // 原型繼承
var f1 = Foo.call(temp);
return f1;
找出原型鏈
1) f1的原型鏈(紅色虛線)吝镣。
- f1為普通對象,它的構造器為Foo昆庇,以Foo為原型末贾,原型鏈第一鏈為
f1.__proto__ == Foo.prototype
; - Foo.prototype(注意這邊不是Foo)為json對象整吆,即普通對象拱撵,構造器為Object,以Object為原型表蝙,得出原型鏈第二鏈
Foo.prototype.__proto__ == Object.prototype
; - Object.prototype以Null為原型拴测,原型鏈第三鏈為
Object.prototype.__proto__ == null
;
f1的原型鏈可以用圖形表示:
可以在瀏覽器console打印驗證:
2) Foo的原型鏈(紫色虛線)
- Foo為函數(shù)對象府蛇,它的構造器為Function集索,以Function為原型,原型鏈第一鏈為
Foo.__proto__ == Function.prototype
; - Function.prototype為json對象汇跨,即普通對象务荆,構造器為Object,以Object為原型穷遂,原型鏈第二鏈為
Function.prototype.__proto__ == Object.prototype
; - 最后Object.prototype以Null為原型函匕,原型鏈第三鏈為
Object.prototype.__proto__ == null
;
Foo的原型鏈可以用圖形表示為:
可以在瀏覽器console打印驗證:
3)小結
列出兩種原型鏈的目的是:
當js引擎執(zhí)行對象的屬性或方法時,先查找對象本身是否存在該方法蚪黑,如果不存在則會在原型鏈上查找盅惜。
因而f1擁有Foo、Object的原型方法忌穿,F(xiàn)oo擁有Function抒寂、Object的原型方法。
注意伴网,雖然f1原型鏈其中有一鏈是涉及到函數(shù)對象Foo,但f1并不擁有Function的原型方法妆棒,因為原型鏈并沒有延伸到Function澡腾。
比如下圖中bind是Function的原型方法,f1并沒有擁有糕珊。
總結
如何找出一個對象的原型鏈动分,只需要兩步
- 判斷對象是普通對象還是函數(shù)對象,得出對象的構造器
- 對象.proto = 構造器.prototype
關于最上面的圖形红选,只剩Object和Function的特殊關系和構造函數(shù)constructor沒有講到澜公,如果有講不清和講錯了的地方,請幫我指出來,我也跟大家一起在學習中坟乾,請輕噴(●ˇ?ˇ●)