在原型继承中实现实例方法/变量

amb*_*tch 5 javascript

在阅读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)

stockpileloadAmmo这绝对是在原型,因为这两个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实际拥有stockpileloadAmmo在他们的对象中,所以javascript查找继承链到他们的共同祖先.

当然我可以手动设置GunDepot的库存,正如预期的那样,解释器不再需要查找链条

GunDepot.stockpile = ["Super Nailgun", "Boomstick"];
alert(GunDepot.stockpile); // outputs "Super Nailgun,Boomstick"
Run Code Online (Sandbox Code Playgroud)

但这不是我想要的.如果这是经典继承(比如Java),loadAmmo将独立地操作MissileDepot和GunDepot的库存,作为实例方法和实例变量.我希望我的原型能够声明孩子们常见的东西,而不是他们分享的东西.

所以也许我完全误解了原型继承背后的设计原则,但我不知道如何实现我刚刚描述的内容.有小费吗?提前致谢!

nau*_*tur 8

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退伍军人更容易.请深入了解原型继承和动态对象创建,因为其中真正的魔力!:)