Javascript 在JS中动态创建函数

Javascript 在JS中动态创建函数,javascript,Javascript,我正在为JS游戏创建AI引擎,它由有限状态机组成。我正在从XML加载状态数及其变量值。我还想加载该行为,因为我没有时间创建脚本语言,所以我认为在外部文件(XML节点内部)上“插入”JS代码并按需执行是个好主意 诸如此类 <evilguy1> <behaviour> this.x++; </behaviour> <behaviour> this.y++; </behaviour&g

我正在为JS游戏创建AI引擎,它由有限状态机组成。我正在从XML加载状态数及其变量值。我还想加载该行为,因为我没有时间创建脚本语言,所以我认为在外部文件(XML节点内部)上“插入”JS代码并按需执行是个好主意

诸如此类

<evilguy1>
    <behaviour>
        this.x++;
    </behaviour>
    <behaviour>
        this.y++;
    </behaviour>
</evilguy1>
我的问题是,现在我已经加载了代码,如何执行它?我想为每个代码“节点”创建一个具有唯一名称的函数,然后从游戏逻辑中调用它们,但我不知道这是否可行(因为您可以从HTML加载更多JS代码,您也应该能够从JS代码中执行,不是吗?)。如果没有,是否有类似的解决方案?提前谢谢

(注:对外部库的依赖越少越好)

编辑1:

现在我知道了如何创建函数来包含代码

window[classname] = function() { ... };

假设您有一个节点名称数组和一个函数体的并行数组:

var functions = {};
var behaviorsNames = ['behavior1', 'beahvior2'];
var behaviorsBodies = ['this.x++', 'this.y++'];
for (var i = 0; i < behaviorsNames.length; i++){
    functions[behaviorsNames[i]] =  new Function(behaviorsBodies[i]);
}

//run a function
functions.behavior1();
var函数={};
var behaviorsNames=['behavior1','beahvior2'];
var behaviorsBodies=['this.x++','this.y++';
对于(var i=0;i
或作为全球成员:

var behaviorsNames = ['behavior1', 'beahvior2'];
var behaviorsBodies = ['this.x++', 'this.y++'];
for (var i = 0; i < behaviors.length; i++){
    window[behaviors[i]] = new Function(behaviorsBodies[i]);
}
var behaviorsNames=['behavior1','beahvior2'];
var behaviorsBodies=['this.x++','this.y++';
对于(变量i=0;i
好吧,您可以使用
函数
构造函数,如本例所示:

var f = new Function('name', 'return alert("hello, " + name + "!");');
f('erick');
这样,您就定义了一个带有参数和body的新函数,并将其分配给变量f。您可以使用哈希集并存储许多函数:

var fs = [];
fs['f1'] = new Function('name', 'return alert("hello, " + name + "!");');
fs['f1']('erick');

加载xml取决于它是在浏览器还是服务器上运行。

扩展Ericks关于函数构造函数的回答

函数构造函数创建一个匿名函数,在运行时出错时,该函数将为调用堆栈中的每个函数(使用函数创建)打印匿名。这可能会使调试更加困难

通过使用一个实用函数,您可以动态命名您创建的函数并绕过这个难题。此示例还将函数数组中每个函数的所有主体合并为一个,然后将所有内容作为一个命名函数返回

const _createFn = function(name, functions, strict=false) {

    var cr = `\n`, a = [ 'return function ' + name + '(p) {' ];

    for(var i=0, j=functions.length; i<j; i++) {
        var str = functions[i].toString();
        var s = str.indexOf(cr) + 1;
        a.push(str.substr(s, str.lastIndexOf(cr) - s));
    }
    if(strict == true) {
        a.splice(1, 0, '\"use strict\";' + cr)
    }
    return new Function(a.join(cr) + cr + '}')();
}
const\u createFn=function(名称、函数、strict=false){
var cr=`\n`,a=['返回函数'+name+'(p){'];

对于(var i=0,j=functions.length;我认为您需要详细说明并可能显示一些代码…
eval
,但要小心,因为它是邪恶的。@Triode感谢命名问题非常有用。现在我只需要弄清楚如何处理代码加载。您能否明确说明这一点:“使调试更加困难”?最后,举个例子会很有帮助。您好,我的意思是,在出现运行时错误时,堆栈跟踪和调试器会打印出自定义名称,而不是“匿名”对于每个创建的函数。我可以更新帖子。你能展示一下在它被实例化后调用它吗?我不习惯调用_常量来使用函数。谢谢你,@MetalGodwin,谢谢你发布了Mozilla文档中关于函数构造函数的引文,从中我学到了很多东西,为最终解决这个问题铺平了道路将我带到该页面的问题。感谢您简洁地回答将我带到该页面的问题。结合@MetalGodwin添加的信息,我成功地解决了该问题。现在我只需解决一个跨来源问题,我就可以自由回家了。
const _createFn = function(name, functions, strict=false) {

    var cr = `\n`, a = [ 'return function ' + name + '(p) {' ];

    for(var i=0, j=functions.length; i<j; i++) {
        var str = functions[i].toString();
        var s = str.indexOf(cr) + 1;
        a.push(str.substr(s, str.lastIndexOf(cr) - s));
    }
    if(strict == true) {
        a.splice(1, 0, '\"use strict\";' + cr)
    }
    return new Function(a.join(cr) + cr + '}')();
}