2015-07-19 114 views
2

我在JavaScript中實現了從父類繼承的函數。它適用於這種風格的代碼。在對象原型中定義繼承

function Foo(){} 

Foo.prototype = { 
    constructor: Foo, 
    name: 'foo', 
    tostring: function() 
    { 
     return this.name; 
    } 
}; 

function Bar(){} 

Bar.prototype = new Foo(); 
Bar.prototype.name = 'bar'; 

var b = new Bar(); 
console.log(b.tostring()); // says 'bar' 

這沒關係。但是我在Bar中有很多屬性,我不想每次重複Bar.prototype.someProp,所以我使用了簡寫版本,並且它不是繼承。

function Bar(){} 
Bar.prototype = new Foo(); 
Bar.prototype = { 
    constructor: Bar, 
    name: 'bar' 
}; 

console.log(b.tostring()); // doesn't work since the method doesn't exist 

我假設Bar.prototype被本地對象的Javascript覆蓋。我如何繼承使用簡寫Bar.prototype = {}並避免重複?

+0

你爲什麼要修改的原型,而不是對象只是定義函數? – David

+2

請仔細闡述,@David – Hawk

+0

請參閱:http://google.github.io/styleguide/javascriptguide.xml?showone=Method_and_property_definitions#Method_and_property_definitions 爲了調試和語言的安全性,最好不要觸摸通常是一個物體的原型。 – David

回答

2

如果您使用...

Bar.prototype = { 
    constructor: Bar, 
    name: 'bar' 
}; 

...你在Bar原型覆蓋了一切,有一個新的對象替換它。嘗試單獨設置Bar.prototype.constructor = xxxBar.prototype.name = 'bar'

你可以定義一個輔助函數,以減少重複,但它可能是不值得的,如果你只需要一次:

function extend_with(obj, kv) { 
    for (var k in kv) { 
     obj[k] = kv[k]; 
    } 
} 

extend_with(Bar.prototype, { 
    constructor: Bar, 
    name: 'bar' 
}); 
+0

如果我單獨使用它,將會有太多的重複我想避免。 – Hawk

+1

沒關係 - 你不能直接用對象設置原型,它會覆蓋原型中已經存在的所有東西。在一些JavaScript庫中有輔助函數可以單獨複製屬性(例如Prototype.js中的Object.extend)。爲此,ECMAScript 6將具有'Object.assign':https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign – thomasfuchs

+0

@thomasfuchs對不起,我剛添加了另一個變體到你的答案。它對你來說看起來合理嗎? – melpomene