2011-08-11 156 views
2

我在秋季參加了我的第一個OOP課程(學習Java),所以我一直在閱讀它,並在學校之前通過一些簡短的語言介紹讓自己熟悉。我很高興能學習Java,但覺得我更喜歡使用JavaScript。我已經完成了一些項目,並且正在通過在JS中使用OOP將我的代碼帶到下一個更專業的級別(如果你想這麼說)。Javascript OOP和繼承技巧

目前我正在努力拖動腳本,並使其與程序編程非常緊密。由於這個項目在我的記憶中是新鮮的,我從這個項目開始開始移動到對象。讓我在這裏絆倒的是有一個'Drag'對象的想法。 。 。

function Drag() { 
    /* Drag code goes here */ 
} // constructor 

我對OOP的想法很滿意,但是這讓我很難過。在我經歷的所有例子中,對象總是,好的,對象。他們是動物或汽車,或自行車等。我還沒有碰到行爲的對象。我只是不確定它會如何工作。 。 。如果您有任何意見,我會很感激。

現在繼承!我還沒有使用繼承,但是這個主題讓我感興趣的是JavaScript,因爲有那麼多人把他們的2美分左右。儘管如此,我認爲最流行的方式是John Resig'sDouglas Crockford's繼承方式。

我認爲他們是非常整潔的解決方法,但由於某種原因,我不太喜歡他們都需要分配。我想我只是覺得他們不應該這樣工作。所以,通過一些例子,在Crockford的方法尋找後,我本想出了(很抱歉,如果別人已經有了,我還沒有看到它):

Object.prototype.extend = function (Obj) { 
    'use strict'; // for jslint 

    this.prototype = new Obj(); 
    this.prototype.constructor = this; 
    return this; 
} 

這裏是它的一個例子使用時,我偷的例子從here然後修改它一下:

Object.prototype.inObj = 1; 

function A() { 
    'use strict'; 
    this.inA = 2; 
} 

A.prototype.inAProto = 3; 

function B() { 
    'use strict'; 
    this.inB = 4; 
} 

/*** HERE IT IS ***/ 
B.extend(A); 

B.prototype.inBProto = 5; 

var w = new A(); 
var x = new B(); 

document.body.innerHTML = x.inObj + ', ' + x.inA + ', ' + x.inAProto + ', ' + x.inB + ', ' + x.inBProto; // 1, 2, 3, 4, 5 
document.body.innerHTML += '<br />'; 
document.body.innerHTML += w instanceof A && w instanceof Object && x instanceof B && x instanceof A && x instanceof Object; // true 

對我來說,它看起來和感覺語法不錯,我不知道JS開發者如何將豐富的感覺了。我測試了它,並且我知道,您可以在B的定義之前放置B.extend(A),但不能將它放在B.prototype.inBProto之後,否則該列表將變爲1,2,3,4,因爲在extend方法中,B的原型正在重啓。我正在解決這個問題,但覺得B.extend(A)應該直接在構造函數的定義之後。

你們都這麼想?提前致謝!

編輯:我公司開發的[笨拙]解決辦法,基本上需要繼承的對象原型的所有屬性,然後將其添加回它被擦拭的新對象乾淨後:

Object.prototype.extend = function (Obj) { 
    'use strict'; 
    var proto, p; 

    proto = {}; 
    for (p in this.prototype) { 
     if (this.prototype.hasOwnProperty(p)) { 
      proto[p] = this.prototype[p]; 
     } 
    } 

    this.prototype = new Obj(); 
    this.prototype.constructor = this; 

    for (p in proto) { 
     if (proto.hasOwnProperty(p)) { 
      this.prototype[p] = proto[p]; 
     } 
    } 

    return this; 
}; 

誰知道,也許你不會認爲這跟我一樣笨拙,但它有效,我覺得它很酷! :D

+0

強烈勸阻增加的Object.prototype,因爲它可能會破壞(第三方)代碼。我目前正在撰寫關於JavaScript面向對象和繼承的入門書。這對你來說可能很有意思,但是,我需要再過幾天,因爲我在業餘時間這樣做。 –

+0

@Daniel Baulig胡,拍。我想你是對的,雖然我不確定如何。我不明白爲什麼會打破其他代碼。 。 。 – dunnza

+0

也同意@Daniel,但是如果你想擴展對象,你可能希望在對象屬性中包含「__defineGetter__」和「__defineSetter__」。 :) – Ragnar

回答

2

我同意丹尼爾,你不應該延伸基本的JS核心。

我可以打破的原因是別人可能也這樣做了。但更重要的是不要更改核心代碼的默認行爲。

我會用不同的方法。而是爲了擴展Object使其成爲功能和使用apply

做了一個簡單的樣機:http://jsfiddle.net/djEw8/

在這裏閱讀關於適用:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/function/apply

+0

所以我認爲即使我把它封裝在類似'if(Object.prototype.extend!=='function'||!Object.prototype.extend)'的東西里,它也會被認爲是一個壞主意來擴充Object原型。 – dunnza

+0

@Zach:你會在「其他」情況下采取什麼合理的行動?使用不同的方法名稱? *如果*與其他東西衝突怎麼辦?最後,這不值得。 –

+0

@just somebody:如果函數已經存在,則不需要其他情況,它只是沒有定義它。 – dunnza