javascript是怎麼繼承的

來源:互聯網
上載者:User

關於js中的繼承,網上有很多文章了,在這裡我寫出自己對js中的繼承的理解。

第一個階段:

function A(){
   this.funB = function(){
       alert('A:funB');
   };
}
A.prototype = {
   funA:function(){
        alert('A:funA');
   }
};
function B(){
}
function extend(sub,parent){
   sub.prototype = new parent();
   sub.prototype.constructor = sub;
}
extend(B,A);
var b = new B();
b.funA(); // out 'A:funA'
b.funB(); // out 'A:funB' 
alert(b instanceof A); // out "true"

想必大家一眼就看出什麼意思了,先是定義了A,B兩個類,然後使用extend方法來讓B繼承A類。extend的原理就是讓父類 new 到子類的prototype上。

用instanceof來檢測也為true,想要讓instanceof為true,那就必須兩個類的prototype對象要為同一個object,不管是間接或直接的。

這樣的方式有沒有問題呢?在通常物件導向語言中,子類在繼承父類時,是不會觸發父類的建構函式執行,而這裡是父類是在繼承時執行的。

第二個階段

function A(){
   this.Astr = 'hello A';
}
A.prototype = {
   funA:function(){
      alert(this.Astr);
   }
};
function B(){
   arguments.callee.superclass && arguments.callee.superclass.apply(this,arguments);
   this.Bstr = 'hello B';
}
B.prototype = {
   funB:function(){
      alert(this.Bstr);
   }
};
function C(){
   arguments.callee.superclass && arguments.callee.superclass.apply(this,arguments);
   alert(this.Astr);
   alert(this.Bstr);
}
function extend(sub,parent){
    var subproto = sub.prototype;
    sub.prototype = parent.prototype;
    typeof subproto != 'object' && (subproto = {});
    typeof sub.prototype != 'object' && (sub.prototype = {});
    for(var i in subproto){
       sub.prototype[i] = subproto[i];
    }
    sub.superclass = parent;
}
//B 繼承 A
extend(B,A);
//C 繼承 B
extend(C,B);
var c = new C(); // out 'hello A','hello B'
c.funA(); //out 'hello A'
c.funB(); // out 'hello B'
alert(c instanceof A) // out true
alert(c instanceof B) // out true;

 這裡對extend方法做了一些改動,這裡有個約定,每個子類都擁有一個superclass的屬性,用來引用她所繼承的父類,用一個空函數proto來獲得父類的prototype,執行個體化給子類的prototype,這樣就沒有執行父類構造器。

而是在子類的構造器中用下來一段代碼來執行約定要的父類構造器。

arguments.callee.superclass && arguments.callee.superclass.apply(this,argumengs);

這樣就完成了類的繼承。

對於上面的代碼有沒有更方便的繼承寫法呢,修改Function的原型來看看:

Function.prototype.extend = function(parent){
    var subproto = this.prototype;
    this.prototype = parent.prototype;
    typeof subproto != 'object' && (subproto = {});
    typeof this.prototype != 'object' && (this.prototype = {});
    for(var i in subproto){
        this.prototype[i] = subproto[i];
    }
    this.superclass = parent;
    return this;
}
function A(){
   this.Astr = 'hello A';
}
A.prototype = {
   funA:function(){
      alert(this.Astr);
   }
};
var B = function(){
   arguments.callee.superclass && arguments.callee.superclass.apply(this,arguments);
   this.Bstr = 'hello B';
}
B.prototype = {
   funB:function(){
      alert(this.Astr);
   }
};
B.extend(A);
var C = function(){
   arguments.callee.superclass && arguments.callee.superclass.apply(this,arguments);
   alert(this.Astr);
   alert(this.Bstr);
}.extend(B);

var c = new C(); // out 'hello A','hello B'
c.funA(); //out 'hello A'
c.funB(); // out 'hello B'
alert(c instanceof A) // out true
alert(c instanceof B) // out true;

 這裡的extend做的事情是: subproto引用子類的原prototype ,將子類的prototype 指向 父類的prototype對象,這樣就繼承了父類(這樣的目的是讓 子類執行個體 instanceof 父類 為 true)。然後曆遍subproto,將原prototype的成員添加到現prototype上,這樣子類重名的重名的成員就會覆蓋父類的成員。最後將子類的屬性superclass 指向 父類。

js繼承的關鍵就是保持原型鏈的唯一性,instanceof就以判斷執行個體的__proto__是否和父類的prototype為同一Object.

今天就寫這樣多,天黑了,下班咯

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.