javascript原型鏈

來源:互聯網
上載者:User
  1. window.onload = function(){      
  2.  2        /**//*  
     
  3.  3           每個對象執行個體都有個屬性成員用於指向到它的instanceof 對象(暫稱為父物件)的原型(prototype)  
     
  4.  4           我們把這種層層指向父原型的關係稱為[原型鏈 prototype chian]  
     
  5.  5           原型也具有父原型,因為它往往也是一個對象執行個體,除非我們人為地去改變它  
     
  6.  6            
  7.  7            
  8.  8           在JavaScript中,"一切都是對象,函數是第一型。"  
     
  9.  9           Function和Object都是函數的執行個體。    
  10. 10           Function的父原型指向到Function的原型,Function.prototype的父原型是Object的原型  
     
  11. 11           Object的父原型也指向到Function的原型,Object.prototype 是所有父原型的頂層  
     
  12. 12            
  13. 13           在spiderMonkey引擎中,父原型可以通過 __proto__ 進行訪問  
     
  14. 14            
  15. 15            
  16. 16            
  17. 17           大家在看的時候最後能反覆的讀幾篇,能加深理解,尤其是原型,父原型,還有原型鏈的意思.  
     
  18. 18               
  19. 19        *  prototype  訪問的是原型    
  20. 20        *  __proto__  訪問的父原型    
  21. 21        *  instanceof 原型鏈的父類    
  22. 22               
  23. 23        */      
  24. 24        Function.prototype.hi = function(){alert('hi Function');}      
  25. 25        Object.prototype.hi = function(){alert('hi Object');}      
  26. 26              
  27. 27        var a = function(){      
  28. 28            this.txt = 'a';      
  29. 29        };      
  30. 30        a.prototype = {      
  31. 31            say:function(){alert('a');}      
  32. 32        };      
  33. 33              
  34. 34        alert(a instanceof Function);//a是Function的執行個體;   
      
  35. 35        alert(a.__proto__ === Function.prototype);      
  36. 36        //a的父原型指向到Function的原型;   
      
  37. 37        //a.__proto__父原型 Function   
      
  38. 38        //Function.prototype 父原型 Function   
      
  39. 39              
  40. 40        alert(Function instanceof Object);      
  41. 41        //Function是Object的執行個體;   
      
  42. 42              
  43. 43        alert(Function.__proto__ === Function.prototype);      
  44. 44        //Function的父原型指向到Function的原型;   
      
  45. 45              
  46. 46        alert(Function.prototype.__proto__ === Object.prototype);      
  47. 47        //Function的原型的父原型指向到Object的原型   
      
  48. 48              
  49. 49        alert(Object.__proto__ === Function.prototype);      
  50. 50        //Object的父原型指向到Function的原型;   
      
  51. 51        alert(Object.prototype.__proto__);      
  52. 52        //Object的原型是所有父原型的頂端,它不再具有父原型,所以結果為 null;   
      
  53. 53              
  54. 54              
  55. 55        alert(a.prototype instanceof Object);      
  56. 56        //a的原型也是一個對象      
  57. 57        alert(a.prototype.__proto__ === Object.prototype);      
  58. 58        //a的原型的父原型指向Object的原型   
      
  59. 59    };    

ECMAScript可以識別兩種類型的對象,一種叫做Native Object屬於語言範疇;一種叫做Host Object,由運行環境提供例如document對象,

Dom Node等
Native objects是一種鬆散的結構並且可以動態增加屬性(property),所有的屬性都有一個名字和一個值,這個值可以是另一個對象的引用
或者是內建的資料類型(String, Number, Boolean, Null 或者 Undefined)
下面的這個簡單的例子描述了一個javascript對象是如何設定一個屬性的值和如何讀取屬性的值的。

賦值操作
一個對象的屬性的建立非常簡單,直接通過賦值操作就可以完成屬性的建立。

Java代碼
 
  1. var objectRef = new Object(); //create a generic javascript object.  
var objectRef = new Object(); //create a generic javascript object.

一個名為testNumber的屬性可以這樣建立。

Java代碼
 
  1. objectRef.testNumber = 5;   
  2. /* - or:- */  
  3. objectRef["testNumber"] = 5;  
objectRef.testNumber = 5;/* - or:- */objectRef["testNumber"] = 5;

如果複製的屬性名稱已經存在那麼不會再次建立這個屬性,賦值操作僅僅是重新設定屬性的值

Java代碼
 
  1. objectRef.testNumber = 8;   
  2. /* - or:- */  
  3. objectRef["testNumber"] = 8;  
objectRef.testNumber = 8;/* - or:- */objectRef["testNumber"] = 8;


js對象的原型(prototype)自己本身也可以是對象,也可以有屬性(property),對於js對象的(prototype)的賦值操作跟普通對象屬性的建立

沒什麼不同。

取值操作
在取值操作中property和prototype就不一樣了,先看最簡單的property取值操作。

Java代碼
 
  1. /*為一個對象的屬性賦值,如果這個對象沒有這個屬性,那麼在賦值操作後,這個對象就有這個屬性了 */  
  2. objectRef.testNumber = 8;   
  3. /* 讀出這個屬性的值 */  
  4. var val = objectRef.testNumber;   
  5.   
  6. /* 現在val 就得到了剛才賦予objectRef的值8了*/  
/*為一個對象的屬性賦值,如果這個對象沒有這個屬性,那麼在賦值操作後,這個對象就有這個屬性了 */objectRef.testNumber = 8;/* 讀出這個屬性的值 */var val = objectRef.testNumber;/* 現在val 就得到了剛才賦予objectRef的值8了*/

prototype揭密
[color=blue]
但是所有的對象都可以有prototypes, prototypes自己也是對象,那麼他也可以有prototypes,這樣迴圈下去就形成了一個prototype鏈,

這個鏈當他遇到鏈中隊形的prototype是null時中止。(Object的預設的prototype是null)

Java代碼
 
  1. var objectRef = new Object(); //create a generic javascript object.  
var objectRef = new Object(); //create a generic javascript object.

建立一個新的js對象,這時這個對象的prototype是Null,所以objectRef的prototype鏈只包含一個對象Object.prototype

我們在看下面的代碼

Java代碼
 
  1. /* 構建MyObject1這個類型的建構函式  
  2.    MyObject1 - type.  
  3. */  
  4. function MyObject1(formalParameter){   
  5.     /* 為者對象建立一個屬性名稱字叫testNumber  
  6.     */  
  7.     this.testNumber = formalParameter;   
  8. }   
  9.   
  10. /* 構建MyObject2這個類型的建構函式  
  11.    MyObject2 - type:-  
  12. */  
  13. function MyObject2(formalParameter){   
  14.    /* 為者對象建立一個屬性名稱字叫testString*/  
  15.     this.testString = formalParameter;   
  16. }   
  17.   
  18. /* 下一步的操作會用MyObject1對象替換掉MyObject2預設的prototype屬性*/  
  19. MyObject2.prototype = new MyObject1( 8 );   
  20.   
  21. /* 最後我們建立MyObject2類型的一個對象*/  
  22.   
  23. var objectRef = new MyObject2( "String_Value" );  
/* 構建MyObject1這個類型的建構函式   MyObject1 - type.*/function MyObject1(formalParameter){    /* 為者對象建立一個屬性名稱字叫testNumber    */    this.testNumber = formalParameter;}/* 構建MyObject2這個類型的建構函式   MyObject2 - type:-*/function MyObject2(formalParameter){   /* 為者對象建立一個屬性名稱字叫testString*/    this.testString = formalParameter;}/* 下一步的操作會用MyObject1對象替換掉MyObject2預設的prototype屬性*/MyObject2.prototype = new MyObject1( 8 );/* 最後我們建立MyObject2類型的一個對象*/var objectRef = new MyObject2( "String_Value" );

objectRef這個MyObject2類型的對象有一個prototype的鏈,鏈中的第一個對象是MyObject1對象,MyObject1對象也有prototype,

這個prototype是Object預設的prototype,Object.prototype的prototype是null,至此這條prototype鏈結束。
當一個取值操作發生時,objectRef 的整個prototype鏈就開始工作

NULL→→object.prototype→→boject→→MyObject1→→objectRef

Java代碼
 
  1. var val = objectRef.testString;  
var val = objectRef.testString;

objectRef這個對象的有一個屬性叫做testString,那麼這句代碼會把testString的值賦給val

Java代碼
 
  1. var val = objectRef.testNumber;  
var val = objectRef.testNumber;

在objectRef這個對象裡並沒有testNumber這個屬性,但是val卻的到了值8,而不是undefine,這是因為解譯器在沒有在當前對象找到要找
的屬性後,就會去檢查這個對象的prototype,objectRef的prototype是MyObject1對象,這個對象有testNumber這個屬性,所以val得到8這個值。

Java代碼
 
  1. var val = objectRef.toString;  
var val = objectRef.toString;

現在val是個function的引用,這個function是Object.prototype的property,由於MyObject1和MyObject2都沒有定義toString這個property

所以Object.prototype返回。

Java代碼
 
  1. var val = objectRef.madeUpProperty;  
var val = objectRef.madeUpProperty;

最後val是undefined,因為MyObject1和MyObject2,還有Object都沒有定義madeUpProperty這個property,所以得到的是undefine.

讀操作會讀取在obj自己和prototype 鏈上發現的第一個同名屬性值
寫操作會為obj對象本身建立一個同名屬性(如果這個屬性名稱不存在
這就意味著objectRef.testNumber = 3會在objectRef對象上建立一個property,名字是testNumber,當下一次在要讀取testNumber時

propertype鏈就不會工作,僅僅會得到objectRef的property 3,而MyObject1的testNumber屬性並不會被修改。下面的代碼可以驗證

Java代碼
 
  1. /* 構建MyObject1這個類型的建構函式  
  2.    MyObject1 - type.  
  3. */  
  4. function MyObject1(formalParameter){   
  5.     /* 為者對象建立一個屬性名稱字叫testNumber  
  6.     */  
  7.     this.testNumber = formalParameter;   
  8. }   
  9.   
  10. /* 構建MyObject2這個類型的建構函式  
  11.    MyObject2 - type:-  
  12. */  
  13. function MyObject2(formalParameter){   
  14.    /* 為者對象建立一個屬性名稱字叫testString*/  
  15.     this.testString = formalParameter;   
  16. }   
  17.   
  18. /* 下一步的操作會用MyObject1對象替換掉MyObject2預設的prototype屬性*/  
  19. var obj1 = new MyObject1( 8 );   
  20. MyObject2.prototype = obj1;   
  21.   
  22. /* 最後我們建立MyObject2類型的一個對象*/  
  23.   
  24. var objectRef = new MyObject2( "String_Value" );   
  25.   
  26. alert(objectRef.testNumber);   
  27. objectRef.testNumber = 5;   
  28. alert(objectRef.testNumber);   
  29. alert(obj1.testNumber);  

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.