在阅读 http://javascript.crockford.com/prototypal.html 之后,我一直在研究原型(prototype)继承。并且在理解如何以使用经典继承的方式使用它时遇到了一些问题。也就是说,原型(prototype)继承的所有函数和变量本质上都变成静态的,除非它们被子对象覆盖。考虑这个片段:
var Depot = {
stockpile : [],
loadAmmo : function (ammoType) {
this.stockpile.push(ammoType);
}
};
var MissileDepot = Object.create(Depot);
var GunDepot = Object.create(Depot);
stockpile
和 loadAmmo
绝对应该在原型(prototype)中,因为 MissileDepot 和 GunDepot 都有它们。然后我们运行:
MissileDepot.loadAmmo("ICBM");
MissileDepot.loadAmmo("Photon Torpedo");
alert(MissileDepot.stockpile); // outputs "ICBM,Photon Torpedo"
alert(GunDepot.stockpile); // outputs "ICBM,Photon Torpedo"
这是意料之中的,因为 MissileDepot
和 GunDepot
在它们的对象中实际上都没有 stockpile
或 loadAmmo
,所以 javascript查找其共同祖先的继承链。
当然我可以手动设置 GunDepot 的库存,正如预期的那样,解释器不再需要查找链
GunDepot.stockpile = ["Super Nailgun", "Boomstick"];
alert(GunDepot.stockpile); // outputs "Super Nailgun,Boomstick"
但这不是我想要的。如果这是经典继承(比如 Java),loadAmmo 将作为实例方法和实例变量独立地对 MissileDepot 和 GunDepot 的库存进行操作。 我希望我的原型(prototype)声明 child 共有的东西,而不是他们共享的东西。
所以也许我完全误解了原型(prototype)继承背后的设计原则,但我不知道如何实现我刚才描述的内容。有小费吗?提前致谢!
最佳答案
Javascript 提供了一种方法来按照您习惯的方式执行此操作:) 试试这个:
function Depot() {
this.stockpile = [],
this.loadAmmo = function (ammoType) {
this.stockpile.push(ammoType);
}
};
var MissileDepot = new Depot();
var GunDepot = new Depot();
MissileDepot.loadAmmo("ICBM");
MissileDepot.loadAmmo("Photon Torpedo");
alert(MissileDepot.stockpile); // outputs "ICBM,Photon Torpedo"
alert(GunDepot.stockpile); // outputs ""
然后你可以在运行中添加函数:
MissileDepot.blow = function(){alert('kaboom');}
用另一个对象扩展对象也是一种选择,但您想要的是这样一个事实,javascript 中的 OO 编程是由函数而不是带有 {} 的对象完成的;)
编辑:
我觉得很遗憾写了这个却没有提及:javascript“new”关键字只是为了让 OO 老手更容易使用。请更深入地研究原型(prototype)继承和动态对象创建,因为其中蕴藏着真正的魔力! :)
关于javascript - 在原型(prototype)继承中实现实例方法/变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2107776/