2013-03-20 53 views
0

有點JS新手仍然存在,我試圖理解使用原型和繼承的最好/最乾淨的方法。在JS中編寫原型繼承的最乾淨的方法

通常我寫對象/原型的定義是這樣的:

var Foo = function(data) { 
    this.data = data; 
}; 
Foo.prototype = { 
    someMethod: function() { 
    return "whatever"; 
    } 
}; 

我喜歡這個,因爲我經常正在使用Namespace對象幾層深,所以它實際上可能看起來更像是這樣的:

App.Model.FooModel = function(){...}; 
App.Model.FooModel.prototype = {...}; 

這很好,因爲我不必輸入每個方法的全名來編寫原型,只是名稱,即。 someMethod: function(){}而不是App.Model.FooModel.prototype.someMethod = function(){}

現在,我遇到的問題是我不知道如何做到這一點與繼承在JS。我能得到繼承工作正常,如果我不喜歡這樣寫道:

var Child = function(){...}; 
Child.prototype = new Parent; 
Child.prototype.someMethod = function(){...}; 

...但現在在一個更復雜的應用程序,我們又回到寫出對象的全名的每一個方法,我覺得這既乏味又難以閱讀。

所以,我的問題是:是否有一種乾淨,直接的方式來編寫從另一個對象繼承的原型,除了使用對象的全名附加所有子方法?

謝謝!

回答

4

嗯,這是JavaScript,您可以編寫自己:

function construct (parent, fn, attr) { 
    fn.prototype = new parent(); 

    for (var x in attr) { 
     fn.prototype[x] = attr[x]; 
    } 
    return fn; 
} 

如果你想,但上面是清晰簡單的實現你可以做的hasOwnProperty檢查。該功能將三個步驟封裝成一個。現在,您可以簡單地做:

var Foo = construct(
    Parent, 
    function(data) { 
     this.data = data; 
    }, 
    { 
     someMethod: function() { 
      return "whatever"; 
     } 
    } 
); 

如果你不喜歡的語法你總是可以想出一個更好的。另一種實現方式是簡單地實現attr擴展部分並正常執行繼承:

function extend (obj, attr) { 
    for (var x in attr) { 
     obj.prototype[x] = attr[x]; 
    } 
    return obj; 
} 

再次,爲了清楚起見,簡化了。所以語法現在變成:

var Foo = function(){...}; 
Foo.prototype = new Parent; 
extend(Foo.prototype,{ 
    someMethod : function(){...} 
}); 
+1

'class'是一個保留字,雖然'Class'不是。 – 2013-03-20 02:57:43

+0

@ gumballhead:謝謝,忘了那個。將類更改爲構造函數(無論如何,因爲它返回構造函數,所以更正確) – slebetman 2013-03-20 04:13:51

+0

小心使用'函數構造函數',我相信你正在遮住'window.constructor' ...並不是必須的,但有人可以想象存儲的東西在'window.constructor'中。也許動詞'construct'會更合適。 – 2013-03-20 04:27:14