隨筆 - 12, 文章 - 0, 評論 - 22, 引用 - 0
          數(shù)據加載中……

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

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

                  Function、Object:Js自帶的函數(shù)對象。
                  prototype,每一個函數(shù)對象都有一個顯示的prototype屬性,它代表了對象的原型(Function.prototype函數(shù)對象是個例外,沒有prototype屬性)。
                  __proto__:每個對象都有一個名為__proto__的內部隱藏屬性,指向于它所對應的原型對象(chrome、firefox中名稱為__proto__,并且可以被訪問到)。原型鏈正是基于__proto__才得以形成(note:不是基于函數(shù)對象的屬性prototype)。
                 關于上面提到的函數(shù)對象,我們來看以下例子,來說明:
                  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
          • 通常我們認為o1、o2是對象,即普通對象;f1、f2、f3為函數(shù)。
          • 但是其實函數(shù)也是對象,是由Function構造的,
          • f3這種寫法就跟對象的創(chuàng)建的寫法一樣。f1、f2最終也都像f3一樣是有Function這個函數(shù)構造出來的
          • f1、f2、f3為函數(shù)對象,F(xiàn)unction跟Object本身也是函數(shù)對象。
                 Js中每個對象(null除外)都和另一個對象相關聯(lián),通過以下例子跟內存效果圖來分析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

              /********************* 系統(tǒng)定義的對象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_理解內存分配
                  堆區(qū)圖說明:
           
                  Function.prototype函數(shù)對象圖內部表示prototype屬性的紅色虛框,只是為了說明這個屬性不存在。

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

          二    Prototype跟Constructor關系
          介紹
                   在 JavaScript 中,每個函數(shù)對象都有名為“prototype”的屬性(上面提到過Function.prototype函數(shù)對象是個例外,沒有prototype屬性),用于引用原型對象。此原型對象又有名為“constructor”的屬性,它反過來引用函數(shù)本身。這是一種循環(huán)引用(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元素):


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



          posted on 2013-10-20 23:47 heavensay 閱讀(32455) 評論(13)  編輯  收藏 所屬分類: web-front

          評論

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹  回復  更多評論   

          支持 博主
          2013-10-21 15:31 | 零柒鎖業(yè)

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹[未登錄]  回復  更多評論   

          啥都不說了 解惑了 十分感謝
          2015-04-27 18:47 | dd

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹[未登錄]  回復  更多評論   

          不過我測試的是
          Object.constructor
          返回:function Function() { [native code] }
          Object.prototype.constructor
          返回:function Object() { [native code] }
          也不是同一個啊 圖中畫的指向是同一個 這是怎么回事兒?望解惑
          2015-04-27 18:54 | dd

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹[未登錄]  回復  更多評論   

          Object.constructor
          返回:function Function() { [native code] }
          Object.prototype.constructor
          返回:function Object() { [native code] }

          都回指向內部__proto__
          2015-05-07 16:21 | bb

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹  回復  更多評論   

          @dd
          Object.constructor,其實是取取值于Function.prototype中的Constructor,即為Function.而Object.prototype.Constructor卻是指向構造該對象的函數(shù)即,Object函數(shù).
          2015-06-01 18:30 | 天厴

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹  回復  更多評論   

          (i.e. Animal.prototype.constructor===Animal)
          這句的前提是 Animal沒有原型對象, 否則應該全等于原型對象所處的類型本身。
          2015-07-08 16:53 | 店小二

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹[未登錄]  回復  更多評論   

          Function.prototype沒有prototype屬性,作為函數(shù)對象有什么用?為什么不直接令他為普通對象
          2015-08-06 23:32 | wu

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹  回復  更多評論   

          為啥object其實是一個函數(shù)對象。js里萬物皆對象。。但object的原型屬性為啥要指向function.prototype.不是object本身也有個prototype對象嗎
          2015-09-26 10:11 | 張漢卿

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹  回復  更多評論   

          博主好人
          2015-11-19 10:39 | 秋天的早晨

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹  回復  更多評論   

          @dd
          兩個還是有區(qū)別的
          2015-12-30 15:30 | kingx

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹[未登錄]  回復  更多評論   

          new Animal指向好像錯了,貌似是直接指向Animal.prototype
          2016-01-02 17:43 | lei

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹  回復  更多評論   

          @lei
          確實
          2016-01-05 16:53 | co

          # re: Js中Prototype、__proto__、Constructor、Object、Function關系介紹  回復  更多評論   

          博主寫的這篇文章真牛逼,解惑!
          2016-05-18 10:22 | 馮琨皓

          只有注冊用戶登錄后才能發(fā)表評論。


          網站導航:
           
          主站蜘蛛池模板: 鄂托克旗| 特克斯县| 吉隆县| 溆浦县| 宝应县| 遂溪县| 新建县| 南乐县| 仙桃市| 三亚市| 文水县| 杨浦区| 克山县| 兴国县| 赣榆县| 昌江| 靖西县| 定结县| 马尔康县| 衡南县| 漾濞| 武汉市| 嵊泗县| 西畴县| 淮北市| 洛隆县| 廊坊市| 思南县| 白山市| 阿拉尔市| 洛宁县| 泸西县| 屯门区| 清流县| 大余县| 永泰县| 竹溪县| 嘉善县| 泊头市| 山西省| 锡林郭勒盟|