Js中Prototype、__proto__、Constructor、Object、Function關(guān)系介紹

一 Prototype、proto與Object、Function關(guān)系介紹
Function、Object:Js自帶的函數(shù)對(duì)象。
prototype,每一個(gè)函數(shù)對(duì)象都有一個(gè)顯示的prototype屬性,它代表了對(duì)象的原型(Function.prototype函數(shù)對(duì)象是個(gè)例外,沒(méi)有prototype屬性)。
proto:每個(gè)對(duì)象都有一個(gè)名為proto的內(nèi)部隱藏屬性,指向于它所對(duì)應(yīng)的原型對(duì)象(chrome、firefox中名稱為proto,并且可以被訪問(wèn)到)。原型鏈正是基于proto才得以形成(note:不是基于函數(shù)對(duì)象的屬性prototype)。
關(guān)于上面提到的函數(shù)對(duì)象,我們來(lái)看以下例子,來(lái)說(shuō)明:

       var o1 = {};
        var o2 =new Object();
        
        function f1(){}
        var f2 = function(){}
        var f3 = new Function('str','console.log(str)');
    
        f3('aabb');   // aabb
        console.log('typeof Object:'+typeof Object);            //function
        console.log('typeof Function:'+typeof Function);        //function
        console.log('typeof o1:'+typeof o1);   //object
        console.log('typeof o2:'+typeof o2);   //object
        console.log('typeof f1:'+typeof f1);   //function
        console.log('typeof f2:'+typeof f2);   //function
        console.log('typeof f3:'+typeof f3);   //function

通常我們認(rèn)為o1、o2是對(duì)象,即普通對(duì)象;f1、f2、f3為函數(shù)。
但是其實(shí)函數(shù)也是對(duì)象,是由Function構(gòu)造的,
f3這種寫(xiě)法就跟對(duì)象的創(chuàng)建的寫(xiě)法一樣。f1、f2最終也都像f3一樣是有Function這個(gè)函數(shù)構(gòu)造出來(lái)的
f1、f2、f3為函數(shù)對(duì)象,F(xiàn)unction跟Object本身也是函數(shù)對(duì)象。
Js中每個(gè)對(duì)象(null除外)都和另一個(gè)對(duì)象相關(guān)聯(lián),通過(guò)以下例子跟內(nèi)存效果圖來(lái)分析Function、Object、Prototype、proto對(duì)象間的關(guān)系。

    function Animal(){
        
    }
    var  anim = new Animal();
    
    console.log('***********Animal anim proto*****************');
    console.log('typeof Animal.prototype:' +typeof Animal.prototype);  //object 
    console.log('anim.__proto__===Animal.prototype:'+(anim.__proto__===Animal.prototype));  //true
    console.log('Animal.__proto__===Function.prototype:'+(Animal.__proto__===Function.prototype));  //true
    console.log('Animal.prototype.__proto__===Object.prototype:'+(Animal.prototype.__proto__===Object.prototype));  //true
    
    console.log('***********Function proto*****************');
    console.log('typeof Function.prototype:'+typeof Function.prototype);  //function
    console.log('typeof Function.__proto__:'+typeof Function.__proto__);  //function
    console.log('typeof Function.prototype.prototype:'+typeof Function.prototype.prototype); //undefined
    console.log('typeof Function.prototype.__proto__:'+typeof Function.prototype.__proto__);   //object
    console.log('Function.prototype===Function.__proto__:'+(Function.prototype===Function.__proto__)); //true

    console.log('***********Object proto*****************');
    console.log('typeof Object.prototype:'+typeof Object.prototype);  //object
    console.log('typeof Object.__proto__:'+typeof Object.__proto__);  //function
    console.log('Object.prototype.prototype:'+Object.prototype.prototype);  //undefied
    console.log('Object.prototype.__proto__===null:'+(Object.prototype.__proto__===null));  //null

    console.log('***********Function Object  proto關(guān)系*****************');
    console.log('Function.prototype===Object.__proto__:'+(Function.prototype===Object.__proto__));   //true
    console.log('Function.__proto__===Object.__proto__:'+(Function.__proto__===Object.__proto__));   //true
    console.log('Function.prototype.__proto__===Object.prototype:'+(Function.prototype.__proto__===Object.prototype));   //true

    /********************* 系統(tǒng)定義的對(duì)象Array、Date ****************************/
    console.log('**************test Array、Date****************');      
    var array = new Array();
    var date = new Date();
    console.log('array.__proto__===Array.prototype:'+(array.__proto__===Array.prototype));   //true
    console.log('Array.__proto__===Function.prototype:'+(Array.__proto__===Function.prototype));  //true
    console.log('date.__proto__===Date.prototype:'+(date.__proto__===Date.prototype));    //true
    console.log('Date.__proto__===Function.prototype:'+(Date.__proto__===Function.prototype));     //true

Function、Object、Prototype、proto內(nèi)存關(guān)系圖

111.png

上面的內(nèi)存圖跟堆棧結(jié)構(gòu)可以參照文章 [Javascript_01_理解內(nèi)存分配](http://www.cnblogs.com/fool/archive/2010/10/07/1845226.html

222.png

Function.prototype函數(shù)對(duì)象圖內(nèi)部表示prototype屬性的紅色虛框,只是為了說(shuō)明這個(gè)屬性不存在。

    通過(guò)上圖Function、Object、Prototype關(guān)系圖中,可以得出一下幾點(diǎn):

所有對(duì)象所有對(duì)象,包括函數(shù)對(duì)象的原型鏈最終都指向了Object.prototype,而Object.prototype.proto===null,原型鏈至此結(jié)束。
Animal.prototype是一個(gè)普通對(duì)象。
Object是一個(gè)函數(shù)對(duì)象,也是Function構(gòu)造的,Object.prototype是一個(gè)普通對(duì)象。
Object.prototype.type指向null。
Function.prototype是一個(gè)函數(shù)對(duì)象,前面說(shuō)函數(shù)對(duì)象都有一個(gè)顯示的prototype屬性,但是Function.prototype卻沒(méi)有prototype屬性,即Function.prototype.prototype===undefined,所有Function.prototype函數(shù)對(duì)象是一個(gè)特例,沒(méi)有prototype屬性。
Object雖是Function構(gòu)造的一個(gè)函數(shù)對(duì)象,但是Object.prototype沒(méi)有指向Function.prototype,即Object.prototype!==Function.prototype。

二 Prototype跟Constructor關(guān)系介紹
在 JavaScript 中,每個(gè)函數(shù)對(duì)象都有名為“prototype”的屬性(上面提到過(guò)Function.prototype函數(shù)對(duì)象是個(gè)例外,沒(méi)有prototype屬性),用于引用原型對(duì)象。此原型對(duì)象又有名為“constructor”的屬性,它反過(guò)來(lái)引用函數(shù)本身。這是一種循環(huán)引用(i.e. Animal.prototype.constructor===Animal)。
通過(guò)以下例子跟內(nèi)存效果圖來(lái)分析Prototype、constructor間的關(guān)系。

    console.log('**************constructor****************'); 

    console.log('anim.constructor===Animal:'+(anim.constructor===Animal))    ;    //true
    console.log('Animal===Animal.prototype.constructor:'+(Animal===Animal.prototype.constructor))    ;    //true
    console.log('Animal.constructor===Function.prototype.constructor:'+(Animal.constructor===Function.prototype.constructor));   //true
    console.log('Function.prototype.constructor===Function:'+(Function.prototype.constructor===Function));    //true
    console.log('Function.constructor===Function.prototype.constructor:'+(Function.constructor===Function.prototype.constructor));    //true

    console.log('Object.prototype.constructor===Object:'+(Object.prototype.constructor===Object));    //true
    console.log('Object.constructor====Function:'+(Object.constructor===Function));    //true

prototype、constructor內(nèi)存關(guān)系圖(在Function、Object、Prototype關(guān)系圖上加入constructor元素):

333.png

上圖中,紅色箭頭表示函數(shù)對(duì)象的原型的constructor所指向的對(duì)象。
注意Object.constructor===Function;本身Object就是Function函數(shù)構(gòu)造出來(lái)的
如何查找一個(gè)對(duì)象的constructor,就是在該對(duì)象的原型鏈上尋找碰到的第一個(gè)constructor屬性所指向的對(duì)象。
參考:
javascript原理介紹
JavaScript 的原型對(duì)象 Prototype
理解js中的原型鏈,prototype與proto的關(guān)系

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容