講解用到的代碼很簡單,以下json
function Foo(){
//屬性和方法
}
var f1 = new Foo();
var f2 = new Foo();
var o1 = new Object();
var o2 = new Object();
複製代碼
一切皆對象,對象又能夠分爲兩類:瀏覽器
由function創造出來的函數:bash
function f1() {
} // 匿名函數
var f2 = function() {
}
var f3 = new Function('x','console.log(x)');
// 以上都是函數對象
複製代碼
系統內置的函數對象: Function、Object、Array、String、Number ,Function其實充當了函數對象的構造器,好比Object對象的構造源碼實際上是Function Object() {[native code]}的形式,這一點對於理解原型鏈很重要。函數
每一個對象都有__proto__
屬性,用於儲存繼承得來的方法和屬性;每一個函數對象都有prototype
屬性,用於繼承,將其中定義的屬性和方法傳遞給‘後代’(好比實例化)。post
f1爲什麼有Foo、Object的原型方法,其實就是經過原型鏈繼承。繼承的過程能夠表示爲f1.__proto__ = Foo.prototype
,即對象.__proto__ = 構造器.prototype
。學習
new實例實現繼承的過程其實與上面原理相同,new的過程能夠拆解爲下面幾個步驟:ui
var temp = {};
temp.__proto__ = Foo.prototype; // 原型繼承
var f1 = Foo.call(temp);
return f1;
複製代碼
f1.__proto__ == Foo.prototype
;Foo.prototype.__proto__ == Object.prototype
;Object.prototype.__proto__ == null
;f1的原型鏈能夠用圖形表示:spa
能夠在瀏覽器console打印驗證:prototype
Foo.__proto__ == Function.prototype
;Function.prototype.__proto__ == Object.prototype
;Object.prototype.__proto__ == null
;Foo的原型鏈能夠用圖形表示爲:3d
能夠在瀏覽器console打印驗證:列出兩種原型鏈的目的是:
當js引擎執行對象的屬性或方法時,先查找對象自己是否存在該方法,若是不存在則會在原型鏈上查找。
於是f1擁有Foo、Object的原型方法,Foo擁有Function、Object的原型方法。
注意,雖然f1原型鏈其中有一鏈是涉及到函數對象Foo,但f1並不擁有Function的原型方法,由於原型鏈並無延伸到Function。
好比下圖中bind是Function的原型方法,f1並無擁有。
如何找出一個對象的原型鏈,只須要兩步
關於最上面的圖形,只剩Object和Function的特殊關係和構造函數constructor沒有講到, 瞭解Object和Function的關係,戳這兒~
若是有講不清和講錯了的地方,請幫我指出來,我也跟你們一塊兒在學習中,請輕噴(●ˇ∀ˇ●)