js怎么實現繼承?


 

3. js怎么實現繼承?

 

  1. 使用原型prototype

  這個問題其實之前總結過了……但是面試時候有點忘……主要思想是記得的,但是不會寫,還是基礎太不牢靠,寫的太少了。一開始因為不知道怎么能繼承父類的方法屬性,同時又不直接使用其原型,所以先寫了一種,子類直接調用父類的原型。但是其中有些過程和方法肯定是寫錯了的……下面是正確的寫法:

  

 1     var Parent = function(name){
 2         this.name = name || "parent"; 3  } 4 Parent.prototype.getName = function(){ 5 return this.name; 6  } 7 8 var Child = function(name){ 9 Parent.apply(this,arguments); //通過apply調用父類的構造函數來進行相同的初始化工作 10  } 11 Child.prototype = Parent.prototype; 12 13 var parent = new Parent("MyParent"); 14 var child = new Child("MyChild"); 15 16 console.log(parent.getName()); //MyParent 17 console.log(child.getName()); //MyChild

//這樣我們就只需要在子類構造函數中執行一次父類的構造函數,同時又可以繼承父類原型中的屬性,這也比較符合原型的初衷,就是把需要復用的內容放在原型中,我們也只是繼承了原型中可復用的內容。

這里如果按序打印 parent, child, Parent, Child,則輸出如下:

 

然后面試官又問如果只想改變子類的原型而不影響父類呢……我想了半天不知道怎么寫,但是因為之前看過,就講了下思想,就是用一個中間變量來存儲其原型,然后給子類new一個……正確方法如下:

//臨時構造函數模式(聖杯模式)(別問我為什么會有一個名字這么中二的方法我也不知道)
//上面借用構造函數模式最后改進的版本還是存在問題,它把父類的原型直接賦值給子類的原型,這就會造成一個問題,就是如果對子類的原型做了修改,那么這個修改同時也會影響到父類的原型,進而影響父類對象,這個肯定不是大家所希望看到的。為了解決這個問題就有了臨時構造函數模式。
var Parent = function(name){
    this.name = name || 'parent' ; } ; Parent.prototype.getName = function(){ return this.name ; } ; Parent.prototype.obj = {a : 1} ; var Child = function(name){ Parent.apply(this,arguments) ;//通過apply調用父類的構造函數來進行相同的初始化工作 } ; var F = new Function(); F.prototype = Parent.prototype ; Child.prototype = new F() ; //通過在父類原型和子類原型之間加入一個臨時的構造函數F,切斷了子類原型和父類原型之間的聯系,這樣當子類原型做修改時就不會影響到父類原型。 var parent = new Parent('myParent') ; var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent console.log(child.getName()) ; //myChild

打印結果:

可以看到Child的實例child會多嵌套一層。

 

然后我發現其實可以不使用中間變量F,直接Child.prototype  = new Parent();也可以。

var Parent = function(name){
    this.name = name || 'parent' ; } ; Parent.prototype.getName = function(){ return this.name ; } ; Parent.prototype.obj = {a : 1} ; var Child = function(name){ Parent.apply(this,arguments) ;//通過apply調用父類的構造函數來進行相同的初始化工作 } ; Child.prototype = new Parent() ; Child.prototype.sayHi = function(){ alert("hi!"); } var parent = new Parent('myParent') ; var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent console.log(child.getName()) ; //myChild parent.sayHi(); //not a function 報錯。說明子類的prototype不會影響到父類

這樣的問題是:父類構造函數被執行了兩次,一次是在子類構造函數中,一次在賦值子類原型時,這是很多余的。

 

那么是否可以不使用apply,直接var Child  = new Function(); Child.prototype = new Parent();呢……這樣絕對不可以!

//這種方法是錯誤的!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

var Parent = function(name){ this.name = name || 'parent' ; } ; Parent.prototype.getName = function(){ return this.name ; } ; Parent.prototype.obj = {a : 1} ; var Child = new Function(); Child.prototype = new Parent() ; var parent = new Parent('myParent') ; var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent console.log(child.getName()) ; //parent

//child是Function對象,其中並沒有name屬性,所以在new一個Child時,括號內的參數是無效的!!!!

那這種方法不是更容易嗎……有什么缺點呢?console.log打印一下parent和child,以及Parent和Child,就會發現問題……

可以看到,打印Parent中是有name屬性的,而Child里沒有name這一屬性。而若是看parent和child兩個實例,就可以看到其實例也沒有name屬性,name是原型的屬性,這個意思就是說,如果Child有多個實例,多個實例的name屬性都會指向同一個name,而不是私有的。

 

 

所以方法就是1和2了  

 

 

 

2. 對象冒充

 1        function Parent(name){
 2             this.name = name;
 3             this.getName = function(){
 4                 return this.name;
 5             }
 6         }
 7         function Child(name,password){
 8             //通過以下3步實現將Parent屬性和方法追加到Child中,從而實現繼承
 9             //第一步:this.method是作為一個臨時的屬性,並且指向Parent所指的對象
10             //第二步:執行this.method方法,即執行Parent所指向的對象函數
11             //第三步:銷毀this.method屬性,即此時Child就已經擁有了Parent的所有屬性和方法
12             this.method = Parent;
13             this.method(name);
14             delete(this.method);
15 
16             this.password = password;
17             this.world = function(){
18                 alert(this.password);
19             }
20         }
21         var child = new Child("Mychild","123456");
22         console.log(child.getName());       //Mychild
23         child.world();                      //123456

 

 

此外可參考博文:http://blog.csdn.net/james521314/article/details/8645815

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM