1. 程式人生 > 其它 >理清javascript中prototype、__proto__、Object、Function的關係,更好地理解原型繼承

理清javascript中prototype、__proto__、Object、Function的關係,更好地理解原型繼承

本文參考了http://www.blogjava.net/heavensay/archive/2013/10/20/405440.html這篇文章,對其內容作了個簡單總結,形成了幾條簡單的結論,讓讀者更容易記住prototype、__proto__、Object、Function之間的關係。

結論1:Object.prototype只是一個普通物件,它是js原型鏈的最頂端。


(typeof Object.prototype) === object;//true
Object.prototype.__proto__=== null;//true
Object.prototype.prototype === undefied;//true

 

Object.prototype只是一個普通物件(普通物件沒有prototype屬性,所以值是undefined),Object.prototype是js原型鏈的最頂端,它的__proto__是null(有__proto__屬性,但值是null,因為這是原型鏈的最頂端)。

 

結論2:在js中如果A物件是由B函式構造的,那麼A.__proto__ === B.prototype。


function Person()
{

}
var obj = {};
alert(obj.__proto__ === Object.prototype);//true
alert(Person.__proto__ === Function.prototype);//true


javascript中物件是由Object建立的,函式是由Function建立的。

 

結論3:內建的Object是其實也是一個函式物件,它是由Function建立的。


Object.__proto__ === Function.prototype;

 

 

結論4:js中每一個物件或函式都有__proto__屬性,但是隻有函式物件才有prototype屬性。


//函式物件
function Person()
{

}

// 普通物件
var obj = {};

obj.__proto__ === Object.prototype;//true
obj.prototype === undefined;//true
Person.__proto__ === Function.prototype;//true
Person.prototype !== undefined;//true

 

我們知道javascript正是通過prototype實現繼承的。如果objA、objB都是由cFunction建立的,那麼根據結論2,objA.__proto__ === objB.__proto__ === cFunction.prototype,也就是說objA和objB物件都繼承了cFunction的prototype。原型鏈是基於__proto__形成的,繼承是通過prototype實現的。

 

 

結論5:Function.prototype是個特例,它是函式物件,但是沒有prototype屬性。其他所有函式都有prototype屬性。
(typeof Function.prototype) === function;//true
Function.prototype.prototype === undefined;//true

 

 

結論6:內建的Function也是一個函式物件,它是通過自己來建立自己的。
(typeof Function.__proto__) === function;//true
Function.__proto__=== Function.prototype;//true


Function這個函式物件,由其自身通過Function函式構造的。

 

結論7:函式也是物件,因為Function.prototype__proto__指向Object.prototype。
(typeof Function.prototype.__proto__) === "object";//true
Function.prototype.__proto__=== Object.prototype;//true

 

 

最後提一下:原型鏈是基於__proto__形成的,繼承是通過prototype實現的。

每個物件都有一個__proto__屬性,原型鏈上的物件正是依靠這個__proto__屬性連結在一起的! 對於原型鏈上的一個物件obj,那麼訪問obj.xxx屬性(方法也是屬性)的過程是: 如果自身有xxx屬性,則訪問它;如果沒有,就通過__proto__屬性找到其原型鏈的上一級原型物件,看它有沒有xxx屬性,如此遞迴查詢,直至找到xxx屬性或到了原型鏈頂端Object.prototype物件為止。

函式擁有prototype屬性,該屬性值是一個object型別。當函式A建立物件B的時候,B物件的__proto__會指向A.prototype,這就是javascript的繼承。