执行从Javascript中的构造函数数组访问的构造函数父级的“静态”方法
哎呀,连这个问题都很难写。问题是:我有一个更像随机模拟器的游戏,它需要从一系列动作中选择一个随机动作,比如:执行从Javascript中的构造函数数组访问的构造函数父级的“静态”方法,javascript,oop,inheritance,Javascript,Oop,Inheritance,哎呀,连这个问题都很难写。问题是:我有一个更像随机模拟器的游戏,它需要从一系列动作中选择一个随机动作,比如: actions = [ Action1, Action2, Action3 ] 我将动作编写为继承自动作父类的类: function Action() { this.targets = []; this.used = []; this.execute = function(player) { doStuff(); return w
actions = [ Action1, Action2, Action3 ]
我将动作编写为继承自动作父类的类:
function Action() {
this.targets = [];
this.used = [];
this.execute = function(player) {
doStuff();
return whatever;
};
}
//btw the below I've seen in a JS OOP tutorial but it doesn't work and I have to implement init() in every child action
Action.init = function(player) {
var a = new this.constructor();
return a.execute(player);
};
Action.checkRequirements = function() {
return true;
};
Action1.prototype = new Action();
Action1.prototype.constructor = Action1;
function Action1 {
this.execute = function(player) {
doStuff();
return whatever;
}
}
Action1.init = function(player) {
var a = new Action1();
return a.execute(player);
}
所以我要执行一个动作并得到它的结果是var foo=actions.getRandomVal.init;getRandomVal是一个简单的自定义脚本,它从数组返回一个随机值。它工作正常,创建正确继承所有属性和方法的对象实例,执行exec方法并返回其结果。。。但是现在我有一个checkRequirements方法,我想在我想要做的100多个动作中的10%中实现它,我想简单地从Action类继承它,这样当它没有在子类中实现时,它只返回true,我不知道如何实现。如果我执行var a=actions.getRandomVal;然后a.检查需求;它抛出一个异常,即a.checkRequirements不是函数
PS:这是一个相对较小的非盈利项目,针对的是一大群朋友,我不需要它在每个浏览器中都工作,它需要在Chrome中工作,我可以告诉他们使用Chrome来完成它。在我看来,你好像在对一个实例调用checkRequirements:
a.checkRequirements();
但它是静态实现的:
Action.checkRequirements = function() {
return true;
};
您可能希望将此函数绑定到原型,因此将上面的代码更改为:
Action.prototype.checkRequirements = function() {
return true;
};
然后,当您希望在派生类型(如Action1)中重写此操作时,可以执行以下操作:
Action1.prototype.checkRequirements = function () {
return (whatever);
}
根据评论,我猜你想要这样的东西
// base Action type providing basic implementation
// Wrapped in an IIFE to prevent global scope pollution
// All functions are prototype bound to allow prototypical inheritance.
var Action = (function () {
function Action() {
this.targets = [];
this.used = [];
};
Action.prototype.doStuff = function () {
return;
}
Action.prototype.execute = function (player) {
this.doStuff();
return "whatever";
}
Action.prototype.checkRequirements = function () {
return "foo";
}
return Action;
})();
var Action1 = (function () {
Action1.prototype = new Action();
Action1.prototype.constructor = Action1;
function Action1() {
}
Action1.prototype.checkRequirements = function () {
// Super call
return Action.prototype.checkRequirements.call(this);
}
return Action1;
})();
var Action2 = (function () {
Action2.prototype = new Action();
Action2.prototype.constructor = Action2;
function Action2() {
}
Action2.prototype.checkRequirements = function () {
return "bar";
}
return Action2;
})();
// Set up array.
var array = [Action1, Action2];
// Create instances (this is where you would pick at random)
var a1 = new array[0]();
var a2 = new array[1]();
// var aofn = new array[rnd]();
// Tests
alert(a1.checkRequirements()); // Should "foo" because it called super (Action).
alert(a2.checkRequirements()); // Should "bar" because it's overridden.
因为您只需要使用Chrome,所以我建议使用ES6类语法,它可以正确地执行所有继承,而不会造成混乱。这包括Action1构造函数从Action构造函数继承属性静态类成员,正如您所期望的那样
class Action {
constructor() {
this.targets = [];
this.used = [];
}
execute(player) {
doStuff();
return whatever;
}
static init(player) {
var a = new this(); // no .constructor
return a.execute(player);
}
static checkRequirements() {
return true;
}
}
class Action1 {
execute(player) {
doOtherStuff();
return whateverelse;
}
}
这不起作用,而且afaik没有实例,我从不调用new,我甚至不知道在数组情况下如何调用。我从一个类数组中选择一个,然后调用它的静态方法。如果我在子操作1中实现静态checkRequirements,它就会起作用——它不会从父操作继承。这是使我在每个子操作中实现init的同一个问题,即使它应该从父操作继承。哦,好吧,我想我也会复制并粘贴检查要求。但留下问题,也许有人会解释。@Deuxis您正在从init函数调用new:var a=new Action1;。让我更新答案……毫无疑问会有一个优雅的解决方案。@Deuxis出于好奇,您是否考虑过先用TypeScript编写此文件并查看编译器生成的内容?@Deuxis请参阅最新的编辑以获得替代解决方案……或者至少可以帮助您开始。谢谢您的帮助,但我首先感到沮丧,然后使用了Bergi答案中的类语法,因为它更简单,更接近我的Java体验,而且有效,所以我无法确认或否认您的答案。但有一件事,我在随机选择的类上调用init——这正是不起作用的,我不能调用应该继承的静态方法,必须为每个子类定义它。Action1.prototype=new Action;这就是为什么谢谢你的原因之一。我仍然不知道为什么静态方法在以旧方式完成时没有被继承,但这是如此简单和优雅,我不在乎。@Deuxis因为在ES5中,子类化只对实例进行继承,而不是对持有静态属性的构造函数进行继承。