1. 程式人生 > >明白JavaScript原型鏈和JavaScrip繼承

明白JavaScript原型鏈和JavaScrip繼承

creat oms 訪問 函數的原型 form eat sub rms amp

原型鏈是JavaScript的基礎性內容之一。其本質是JavaScript內部的設計邏輯。

首先看一組代碼:

 1 <script type="text/javascript">
 2         function parent(){
 3             this.name="cehis";
 4         }
 5 
 6         function son(){
 7             this.age=11;
 8         }
 9 
10         function sub(){
11             this
.sex="nan"; 12 } 13 14 //簡單實現下繼承 15 son.prototype=new parent(); 16 sub.prototype=new son(); 17 18 var sunfromsub=new sub(); 19 var sonformson=new son(); 20 console.log(sunfromsub.name,sunfromsub.age,sunfromsub.sex); //cehis 11 nan
21 console.log(sonformson.name,sonformson.age,sonformson.sex); //cehis 11 undefined 22 23 //看一下__proto__這個屬性 24 console.log(sunfromsub.__proto__); 25 console.log(sunfromsub.__proto__.__proto__); 26 console.log(sunfromsub.__proto__.__proto__.__proto__); 27
console.log(sunfromsub.__proto__.__proto__.__proto__.__proto__); 28 console.log(sunfromsub.__proto__.__proto__.__proto__.__proto__.__proto__);//null 29 30 console.log(sonformson.__proto__); 31 console.log(sonformson.__proto__.__proto__); 32 console.log(sonformson.__proto__.__proto__.__proto__); 33 console.log(sonformson.__proto__.__proto__.__proto__.__proto__);//null 34 </script>

總結一下知識點:

prototype是函數的一個屬性(每個函數都有一個prototype屬性),這個屬性是一個指針,指向一個對象。它是顯示修改對象的原型的屬性。

__proto__是一個對象擁有的內置屬性(請註意:prototype是函數的內置屬性,__proto__是對象的內置屬性),是JS內部使用尋找原型鏈的屬性

簡單來說通過級聯訪問__proto__這個屬性,就往js內部原型追溯。一直到null為止。

JavaScript原型鏈就是__proto__形成的鏈條。是一種靜態的結構。

而JavaScript的繼承是JavaScript內部的一種訪問機制。這種機制就是回溯__proto__形成的鏈條。

結果:構造函數的實例可以繼承構造函數自身的和原型上屬性值。一直繼承到null為止。

需要指出的是,JavaScript繼承的方式有不止一種,上述代碼中,構造函數實例既繼承了構造函數的原型數據也繼承了構造函數數據。

如果使用下面的代碼實現繼承:

 1       function parent(){
 2             this.name="cehis";
 3         }
 4         function son(){
 5             this.age=11;
 6         } 
 7     
 8         son.prototype=new parent();
 9            son.prototype.id=111;
10         //只是繼承構造函數原型上屬性也就是繼承id
11         var audience1=Object.create(son.prototype);
12         //既不會繼承構造函數自身屬性也不會繼承構造函數原型屬性
13         var audience2=Object.create(son);
14          
15          console.log(audience1.id,audience1.age,audience1.name); //111 undefined "cehis"
16          console.log(audience2.id,audience2.age,audience2.name); //undefined undefined "son"

使用Object.create創建實例,實現繼承,如果參數是構造函數本身則會繼承構造函數的屬性,但是不會繼承其父元素的原型對象的屬性。

如果參數是原型prototype則會繼承父元素屬性以及構造函數原型屬性。

如果使用apply或者call方式實現繼承。

 1  function parent(name,age) {
 2         this.name =name;
 3         this.age=age;
 4     }
 5     parent.prototype.id=222;
 6     function son(name,age,sex) {
 7         parent.call(this,name,age);
 8         this.sex =sex;
 9     }
10     
11 
12     var example=new son("jack",12,"nan");
13     console.log(example.name,example.age,example.sex,example.id);//jack 12 nan undefined

以上只是繼承了構造函數自身的屬性,而沒有繼承構造函數原型的屬性。apply或者call本身是借用,而不是繼承。

嚴格來說只有new 和 Object.create()才是繼承。才會回溯。

本文結束。

明白JavaScript原型鏈和JavaScrip繼承