JS原型,原型鏈

對象

要清楚原型鏈,首先要弄清楚對象:javascript

 

  • 普通對象

 

 

    • 最普通的對象:有__proto__屬性(指向其原型鏈),沒有prototype屬性。
    • 原型對象(person.prototype 原型對象還有constructor屬性(指向構造函數對象))

 

  • 函數對象:
    • 凡是經過new Function()建立的都是函數對象。
                          擁有__proto__、prototype屬性(指向原型對象)。

                          Function、Object、Array、Date、String、自定義函數java

                          特例: Function.prototype(是原型對象,倒是函數對象,下面會有解釋)

[javascript] view plain copyapp

  1. 函數對象  
  2. function f1(){};  
  3. var f2 = function(){};  
  4. var f3 = function("n1","n2","return n1+n2");  
  5.   
  6. console.log(typeof f1);  //function  
  7. console.log(typeof f2);  //function  
  8. console.log(typeof f3);   //function  
  9. console.log(typeof Object);   //function  
  10. console.log(typeof Array);   //function  
  11. console.log(typeof String);   //function  
  12. console.log(typeof Date);   //function  
  13. console.log(typeof Function);   //function  

Array是函數對象,是Function的實例對象,Array是經過newFunction建立出來的。由於Array是Function的實例,因此Array.__proto__ ===  Function.prototype函數

 

[javascript] view plain copythis

  1. 普通對象  
  2. var o1 = new f1();   
  3. var o2 = {};         
  4. var o3 = new Object();   
  5.   
  6. console.log(typeof o1);  //Object  
  7. console.log(typeof o2);   //Object  
  8. console.log(typeof o3);   //Object  

 

原型對象

 

        每建立一個函數都會有一個prototype屬性,這個屬性是一個指針,指向一個對象(經過該構造函數建立實例對象的原型對象)。原型對象是包含特定類型的全部實例共享的屬性和方法。原型對象的好處是,能夠讓全部實例對象共享它所包含的屬性和方法。spa

        第一塊中有提到,原型對象屬於普通對象。Function.prototype是個例外,它是原型對象,卻又是函數對象,做爲一個函數對象,它又沒有prototype屬性。.net

[javascript]  view plain  copy
  1. function person(){};  
  2.   
  3. console.log(typeof person.prototype) //Object  
  4. console.log(typeof Object.prototype) // Object  
  5. console.log(typeof Function.prototype) // 特殊 Function  
  6. console.log(typeof Function.prototype.prototype) //undefined 函數對象卻沒有prototype屬性  

解釋:prototype

     functionperson(){};指針

        其實原型對象就是構造函數的一個實例對象。person.prototype就是person的一個實例對象。至關於在person建立的時候,自動建立了一個它的實例,而且把這個實例賦值給了prototype。對象

 

[javascript]  view plain  copy
  1.  function person(){};  
  2. var temp = new person();  
  3. person.prototype = temp;  
  4.   
  5. function Function(){};  
  6. var temp = new Function();  
  7. Function.prototype = temp; //由new Function()產生的對象都是函數對象  
 

 

        從一張圖看懂原型對象、構造函數、實例對象之間的關係

 

[javascript]  view plain  copy
  1. function Dog(){};  
  2.   
  3. Dog.prototype.name = "小黃";  
  4. Dog.prototype.age =  13;  
  5. Dog.prototype.getAge = function(){  
  6.     return this.age;  
  7. }  
  8.   
  9. var dog1 = new Dog();  
  10. var dog2 = new Dog();  
  11.   
  12. dog2.name = "小黑";  
  13. console.log(dog1.name); // 小黃 來自原型  
  14. console.log(dog2.name); // 小黑 來自實例  
 

 

 

 

[javascript]  view plain  copy
  1. //圖中的一些關係  
  2. dog1.__proto__ === Dog.prototype  
  3.   
  4. Dog.prototype.__proto__ === Object.prototype //繼承Object 下面原型鏈說  
  5.   
  6. dog1.__proto__.__proto__ === Object.prototype  
  7.   
  8. Dog.prototype.constructor === Dog   
  9.   
  10. Dog.prototype.isPrototypeOf(dog1)  
  11.   
  12. 獲取對象的原型  
  13. dog1.__proto__  //不推薦  
  14. Object.getPrototypeOf(dog1) === Dog.prototype   //推薦  
 

 

原型鏈

原型鏈是實現繼承的主要方法。

 

先說一下繼承,許多OO語言都支持兩張繼承方式:接口繼承、實現繼承。

|- 接口繼承:只繼承方法簽名

|- 實現繼承:繼承實際的方法

因爲函數沒有簽名,在ECMAScript中沒法實現接口繼承,只支持實現繼承,而實現繼承主要是依靠原型鏈來實現。

 

 

原型鏈基本思路:

 

利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。

 

每一個構造函數都有一個原型對象,原型對象都包含一個指向構造函數想指針(constructor),而實例對象都包含一個指向原型對象的內部指針(__proto__)。若是讓原型對象等於另外一個類型的實例,此時的原型對象將包含一個指向另外一個原型的指針(__proto__),另外一個原型也包含着一個指向另外一個構造函數的指針(constructor)。假如另外一個原型又是另外一個類型的實例……這就構成了實例與原型的鏈條。

 

原型鏈基本思路(圖解):

 

 

 

舉例說明:

 

[javascript]  view plain  copy
  1. function animal(){  
  2.     this.type = "animal";  
  3. }  
  4. animal.prototype.getType = function(){  
  5.     return this.type;  
  6. }  
  7.   
  8. function dog(){  
  9.     this.name = "dog";  
  10. }  
  11. dog.prototype = new animal();  
  12.   
  13. dog.prototype.getName = function(){  
  14.     return this.name;  
  15. }  
  16.   
  17. var xiaohuang = new dog();  

 

[javascript]  view plain  copy
  1. //原型鏈關係  
  2. xiaohuang.__proto__ === dog.prototype  
  3. dog.prototype.__proto__ === animal.prototype  
  4. animal.prototype.__proto__ === Object.prototype  
  5. Object.prototype.__proto__ === null  
 

圖解:

 

詳細圖

從xiaohuang這個實例,看出整個鏈條

 

 

總結:

 

Xiaohuang這個Dog的實例對象繼承了Animal,Animal繼承了Object。

相關文章
相關標籤/搜索