Js中Prototype、__proto__、Constructor、Object、Function關係介紹

Js中Prototype、__proto__、Constructor、Object、Function關係介紹

一    Prototype、__proto__與Object、Function關係介紹

        Function、Object:Js自帶的函數對象。
        prototype,每個函數對象都有一個顯示的prototype屬性,它表明了對象的原型(Function.prototype函數對象是個例外,沒有prototype屬性)。
        __proto__:每一個對象都有一個名爲__proto__的內部隱藏屬性,指向於它所對應的原型對象(chrome、firefox中名稱爲__proto__,而且能夠被訪問到)。原型鏈正是基於__proto__才得以造成(note:不是基於函數對象的屬性prototype)。
 
       關於上面提到的函數對象,咱們來看如下例子,來講明:
        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
  • 一般咱們認爲o一、o2是對象,即普通對象;f一、f二、f3爲函數。
  • 可是其實函數也是對象,是由Function構造的,
  • f3這種寫法就跟對象的建立的寫法同樣。f一、f2最終也都像f3同樣是有Function這個函數構造出來的
  • f一、f二、f3爲函數對象,Function跟Object自己也是函數對象。
       Js中每一個對象(null除外)都和另外一個對象相關聯,經過如下例子跟內存效果圖來分析Function、Object、Prototype、__proto__對象間的關係。

    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關係*****************');
    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

    /********************* 系統定義的對象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__內存關係圖


        上面的內存圖跟堆棧結構能夠參照文章 Javascript_01_理解內存分配
        堆區圖說明:
 
        Function.prototype函數對象圖內部表示prototype屬性的紅色虛框,只是爲了說明這個屬性不存在。

         經過上圖Function、Object、Prototype關係圖中,能夠得出一下幾點:
  1. 全部對象全部對象,包括函數對象的原型鏈最終都指向了Object.prototype,而Object.prototype.__proto__===null,原型鏈至此結束。
  2. Animal.prototype是一個普通對象。
  3. Object是一個函數對象,也是Function構造的,Object.prototype是一個普通對象。
  4. Object.prototype.__type__指向null。
  5. Function.prototype是一個函數對象,前面說函數對象都有一個顯示的prototype屬性,可是Function.prototype卻沒有prototype屬性,即Function.prototype.prototype===undefined,全部Function.prototype函數對象是一個特例,沒有prototype屬性。
  6. Object雖是Function構造的一個函數對象,可是Object.prototype沒有指向Function.prototype,即Object.prototype!==Function.prototype。

二    Prototype跟Constructor關係
介紹
         在 JavaScript 中,每一個函數對象都有名爲「prototype」的屬性(上面提到過Function.prototype函數對象是個例外,沒有prototype屬性),用於引用原型對象。此原型對象又有名爲「constructor」的屬性,它反過來引用函數自己。這是一種循環引用(i.e. Animal.prototype.constructor===Animal)。
 
        經過如下例子跟內存效果圖來分析Prototype、constructor間的關係。
    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內存關係圖(在Function、Object、Prototype關係圖上加入constructor元素):


        上圖中,紅色箭頭表示函數對象的原型的constructor所指向的對象。
  1. 注意Object.constructor===Function;自己Object就是Function函數構造出來的        
  2. 如何查找一個對象的constructor,就是在該對象的原型鏈上尋找碰到的第一個constructor屬性所指向的對象。
 
參考:
http://www.libuchao.com/2012/05/14/prototypes-in-javascript/ (JavaScript 的原型對象 Prototype)
http://rockyuse.iteye.com/blog/1426510 (理解js中的原型鏈,prototype與__proto__的關係)
相關文章
相關標籤/搜索