[ JavaScript ] JavaScript 實現繼承.

來源:互聯網
上載者:User

標籤:最好   類的屬性   nbsp   test   html   ceo   對象冒充   這一   article   

對於javascript中的繼承,因為js中沒有後端語言中的類式繼承。所以js中的繼承,一般都是原型繼承(prototype)。

function P (name){this.name = name;this.say = function(){console.log(‘p‘);}}function S (name,id){this.id = id;this.eat = function(){console.log(‘s‘);}}S.prototype = P.prototype;var s = new S();

以上代代碼存在一個重要問題:

S.prototype = P.prototype;

該句代碼會導致,在改動子類的prototype的時候,相同會影響父類的prototype元素。

解決方案一般採用new 父級對象的方式:

S.prototype = new P();
這裡涉及到new 的工作原理,new P(), 會依據P的prototype對象建立一個執行個體,然後將構造方法中的成員變數和成員方法設定進去。

此種方式, 改動子類的prototype則不會影響父類的prototpye(因為是建立了一個對象,不再是指向同一個prototype).

設定prototype之後。還須要重設子類S的contrustor,讓其重指向 S。而不是new P() 所相應的construstor. 例如以下:

S.prototype.constructor = S;

非常多時候這裡不重設。不會出現故障,可是假設後面須要用到constructor 來建立執行個體,或者判定執行個體類型,則會出現錯誤。

所以這裡最好是重設。


上面所述的原型繼承。儘管能夠通過JavaScript原型繼承,可是相同存在不足。

此種繼承方式。不可以繼承在構造方法設定的成員變數和成員方法。僅僅能繼承在原型中設定的方法,或者屬性。

如:

var s = new S(‘yang‘,‘01‘);
當中的第一個參數,並不能傳遞給到name屬性。


於是引出另外一種繼承方式: 對象冒充。

function P (name){this.name = name;this.say = function(){console.log(‘p‘);}}function S (name,id){P.call(this,name);this.id = id;this.eat = function(){console.log(‘s‘);}}var s = new S(‘yanghi‘,‘test‘);

在子類構造方法中,借用父類的構造方法。使子類具有父類的屬性和方法。

例如以下:

P.call(this,name);

該句代碼與例如以下效果一樣:

this.name = name;this.say = function(){}

從而將父類的屬性複製到子類中。從而實現對象冒充。

那麼該此種對象冒充方式。相同存在問題:

1 無法繼承原型prototype中的屬性和主法。

2 構造方法的成員方法在父類和子類中都會有一份拷貝,造成記憶體的添加。


所以最好的實現方式是:

1 對原型對象。採用原型繼承

2 構造方法中的屬性和方法。採用對象冒充。

這也是當前絕大對數的js繼承庫所採用的實現方式。例如以下:

function P (name){this.name = name;}P.prototype.say = function(){console.log(‘say‘);}function S (name,id){P.call(this,name);this.id = id;}function Bare(){}Bare.prototype = P.prototype;S.prototype = new Bare();S.prototype.constructor = S;S.prototype.eat = function(){console.log(‘eat‘);}var s = new S(‘yanghi‘,‘test‘);

這裡的成員屬性。採用對象冒充,成員方法採用原型繼承。

注意一點。這裡實現原型繼承須要採用一個中間變數。例如以下:

S.prototype = new Bare();

假設不採用中間變數。直接new P() 的話,會出現故障。

因為new 會依照P的prototype對象模版,建立一個對象,這一步沒有問題。

可是接下來。它會將P構造方法的成員屬性也設定到這個對象中,就會導致對這個對象汙染。

這裡我們僅僅須要它的prototype就能夠了。其他的成員變數採用對象冒充的方式就能夠了。


第三種實現繼承方式,採用ES5 Object.create實現。

//Shape - superclassfunction Shape() {  this.x = 0;  this.y = 0;}Shape.prototype.move = function(x, y) {    this.x += x;    this.y += y;    console.info("Shape moved.");};// Rectangle - subclassfunction Rectangle() {  Shape.call(this); //call super constructor.}Rectangle.prototype = Object.create(Shape.prototype);var rect = new Rectangle();rect instanceof Rectangle //true.rect instanceof Shape //true.rect.move(1, 1); //Outputs, "Shape moved."

只是此方式最大的問題還是相容性,須要 IE 9 + , safari 5 +,opera 11.6 + 


以上就是對象繼承的一些問題,以記錄之,謹防忘記。


[ JavaScript ] JavaScript 實現繼承.

聯繫我們

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