我想實現一種在JavaScript中實現繼承的方法。首先我定義基類,如下所示:爲什麼我不能從內部重新定義函數的原型
function Person(name){
name = name + "!"; //I want to reuse this code for initialization
this.getName = function(){
return name;
};
this.setName = function(_name){
name = _name;
};
};
然後我定義子類。發生,我需要一種方法來調用基類的構造函數。理想情況下,我會從VipPerson
構造函數中調用它,當我仍然有參考name
param。但是,如果我從這一點做它根本不工作,如果我嘗試從基類訪問getName
我得到一個錯誤VipPerson has no getName method
。
function VipPerson(name, vipLevel){
this.getVipLevel = function(){
return vipLevel;
};
//the line below would not work!
//VipPerson.prototype = new Person(name);
};
VipPerson.prototype = new Person(); //but this would. not ideal IMO
的缺點爲我設置爲從VipPerson
外的原型是我失去了參數的任何引用被傳遞。
有沒有一種優雅的方式來解決這個問題?我想要這個乾淨的界面:
var foo = new Person("Foo");
console.log(foo.getName());
var bar = new VipPerson("Bar", 100);
console.log(bar.getName()); //error
console.log(bar.getVipLevel());
請注意,就是這樣,你沒有做繼承,就像問題似乎問:'var vp = new VipPerson(「John」);警報(vp instanceof Person)// false'。爲了獲得適當的繼承,您需要正確設置'prototype'。詳情請參閱我的回答。 – ZER0 2012-07-29 20:16:12
是的,你是正確的@ZERO。雖然你答案實現繼承,但它可能會導致一個非常大的錯誤。當你將函數「call」作爲參數傳遞給「this」時,你正在複製VipPerson中Person的所有屬性。更改原型,將在原型中創建相同的屬性。 – 2012-07-30 11:21:34
這不是一個錯誤,這就是繼承的作用。如果'Person'有一個'foo'方法,我也想'VipPerson'。構造函數動態擴展對象的事實與我的提議或繼承無關,而是與原始代碼有關,我明確表示不應該這樣做。最好使用'prototype'來定義方法,但是在這種情況下你不能真正擁有「私有」(通常在JS中它很好)。 '__proto__'的新編輯不是標準的,不能用於交叉瀏覽。 – ZER0 2012-07-30 15:50:17