Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/423.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
执行从Javascript中的构造函数数组访问的构造函数父级的“静态”方法_Javascript_Oop_Inheritance - Fatal编程技术网

执行从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中,子类化只对实例进行继承,而不是对持有静态属性的构造函数进行继承。