actions = [ Action1, Action2, Action3 ]
我将操作编写为继承自Action父类的类:
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.checkRequirements();
它会抛出一个异常,即a.checkRequirements不是函数。
答案 0 :(得分:1)
由于您只需要使用Chrome,我建议使用ES6 class
语法,该语法可以正确地执行所有继承,而不会陷入困境。这包括您的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;
}
}
答案 1 :(得分:0)
我认为您在某个实例上调用了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.