js怎麼實現繼承?

 

3. js怎麼實現繼承?面試

 

  1. 使用原型prototypeapp

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

  

 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,則輸出以下:this

 

而後面試官又問若是隻想改變子類的原型而不影響父類呢……我想了半天不知道怎麼寫,可是由於以前看過,就講了下思想,就是用一箇中間變量來存儲其原型,而後給子類new一個……正確方法以下:es5

//臨時構造函數模式(聖盃模式)(別問我爲何會有一個名字這麼中二的方法我也不知道)
//上面借用構造函數模式最後改進的版本仍是存在問題,它把父類的原型直接賦值給子類的原型,這就會形成一個問題,就是若是對子類的原型作了修改,那麼這個修改同時也會影響到父類的原型,進而影響父類對象,這個確定不是你們所但願看到的。爲了解決這個問題就有了臨時構造函數模式。
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

打印結果:spa

能夠看到Child的實例child會多嵌套一層。.net

 

而後我發現其實能夠不使用中間變量F,直接Child.prototype  = new Parent();也能夠。prototype

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不會影響到父類

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

 

那麼是否能夠不使用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

相關文章
相關標籤/搜索