在阅读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);
Run Code Online (Sandbox Code Playgroud)
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"
Run Code Online (Sandbox Code Playgroud)
这是预期的,因为既没有MissileDepot也没有GunDepot实际拥有stockpile或loadAmmo在他们的对象中,所以javascript查找继承链到他们的共同祖先.
当然我可以手动设置GunDepot的库存,正如预期的那样,解释器不再需要查找链条
GunDepot.stockpile = ["Super Nailgun", "Boomstick"];
alert(GunDepot.stockpile); // outputs "Super Nailgun,Boomstick"
Run Code Online (Sandbox Code Playgroud)
但这不是我想要的.如果这是经典继承(比如Java),loadAmmo将独立地操作MissileDepot和GunDepot的库存,作为实例方法和实例变量.我希望我的原型能够声明孩子们常见的东西,而不是他们分享的东西.
所以也许我完全误解了原型继承背后的设计原则,但我不知道如何实现我刚刚描述的内容.有小费吗?提前致谢!
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 ""
Run Code Online (Sandbox Code Playgroud)
然后U可以动态添加功能:
MissileDepot.blow = function(){alert('kaboom');}
Run Code Online (Sandbox Code Playgroud)
使用另一个对象扩展对象也是一种选择,但你想要的是这样的事实,即javascript中的OO编程是由函数而不是{};对象完成的.
编辑:
我不好意思写这篇文章:javascript"new"关键字只是为了让OO退伍军人更容易.请深入了解原型继承和动态对象创建,因为其中真正的魔力!:)
| 归档时间: |
|
| 查看次数: |
3837 次 |
| 最近记录: |