在阅读http://javascript.crockford.com/prototypal.html之后,我一直在玩原型继承,并且在理解如何以使用古典继承的方式使用它方面遇到了一些问题。也就是说,原型继承的所有函数和变量本质上都是静态的,除非它们被子对象覆盖。考虑一下这个片段:
var Depot = {
stockpile : [],
loadAmmo : function (ammoType) {
this.stockpile.push(ammoType);
}
};
var MissileDepot = Object.create(Depot);
var GunDepot = Object.create(Depot);stockpile和loadAmmo绝对应该在原型中,因为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的库存,作为实例方法和实例变量。我希望我的原型能够声明孩子们共有的东西,而不是他们共享的东西。
因此,也许我完全误解了原型继承背后的设计原则,但我不知道如何实现我刚才描述的目标。有小费吗?提前感谢!
发布于 2010-01-21 08:46:41
Javascript提供了一种执行此操作的方法,如U所习惯的那样:)尝试如下:
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老手更容易使用。请深入挖掘原型继承和动态对象创建,因为其中包含了真正的魔力!)
发布于 2010-01-21 08:41:37
对于该方法,所有操作都按预期工作。这只是你需要处理的领域。
我在YUI中看到的是,构造函数分配实例变量。从父类继承的“类”调用父类的构造函数。看这里:http://developer.yahoo.com/yui/docs/DataSource.js.html
示例基类:
util.DataSourceBase = function(oLiveData, oConfigs) {
...
this.liveData = oLiveData;
... more initialization...
}示例子类:
util.FunctionDataSource = function(oLiveData, oConfigs) {
this.dataType = DS.TYPE_JSFUNCTION;
oLiveData = oLiveData || function() {};
util.FunctionDataSource.superclass.constructor.call(this, oLiveData, oConfigs);
};
// FunctionDataSource extends DataSourceBase
lang.extend(util.FunctionDataSource, util.DataSourceBase, {
...prototype of the subclass...
});发布于 2010-01-21 08:35:24
为了实现你想要的,你需要一种克隆方法。你不需要一个继承原型,你需要一个克隆原型。看看已经实现的Object.clone()函数之一,比如prototypejs的一个:方法
如果您想要坚持某种类型的原型化,您必须实现一个初始化()方法,该方法将为您新创建的仓库提供一个库存属性。这就是原型is类的定义方式:克隆的原型和初始化()方法:http://prototypejs.org/learn/class-inheritance
https://stackoverflow.com/questions/2107776
复制相似问题