javascript - 通过字符串名称调用 "local"函数而不使用 eval?

标签 javascript function eval

由于出于多种原因不再使用 eval,我正在处理调用函数的一些问题。所以我正在制作一个“函数调用者”来代替 eval。首先:我是否带回了安全性、速度和调试困难等评估问题?测试代码如下:

function globalFunc(p){
    console.log("Run globalFunc: "+p);
}
var globalVarFunc = function(p){
    console.log("Run globalVarFunc: "+p);
}
function ini(){
    var varFunc = function(p){
        console.log("Run varFunc: "+p);
    }
    //
    funcCaller(function(p){ console.log("Run anonymous function: "+p); }, "anonymous");
    funcCaller('function(p){ console.log("Run anonymous function: "+p); }', "anonymous");
    funcCaller(globalFunc, "global function");
    funcCaller("globalFunc", "global string");
    funcCaller(globalVarFunc, "globalVarFunc function");
    funcCaller("globalVarFunc", "globalVarFunc string");
    funcCaller(localFunc, "local function");
    funcCaller("localFunc", "local string");
    funcCaller(varFunc, "local var function");
    funcCaller("varFunc", "local var string");
    //
    function localFunc(p){
        console.log("Run localFunc: "+p);
    }
}
function funcCaller(func, p){
    if(typeof(func)=="string"){
        p += " as string";
        try { window[func](p); } catch(e) { 
            console.log("Catch window error trying "+p) ;
            try { this[func](p); } catch(e) { console.log("Catch this error trying "+p) }
        }
    } else if(typeof(func)=="function"){
        p += " as function";
        try { func(p); } catch(e) { console.log("Catch error trying "+p) }
    } else {
        console.log("Unknown situation: "+typeof(func)+" trying "+p);
    }
}

Safari 5.1 的日志结果:

Run anonymous function: anonymous as function
Catch window error trying anonymous as string
Catch this error trying anonymous as string
Run globalFunc: global function as function
Run globalFunc: global string as string
Run globalVarFunc: globalVarFunc function as function
Run globalVarFunc: globalVarFunc string as string
Run localFunc: local function as function
Catch window error trying local string as string
Catch this error trying local string as string
Run varFunc: local var function as function
Catch window error trying local var string as string
Catch this error trying local var string as string

也许不建议将匿名函数作为字符串运行,与 eval 存在同样的问题。但是,如果“globalVarFunc”可以工作,为什么“varFunc”不起作用呢?

编辑:我希望在列表中运行“varFunc”。

最佳答案

我认为您缺少的是两个概念之间的关系:

  • 通过引用传递
  • 范围

让我们举一个简单的例子:

function check(arg) {
    try {
        var func = new Function('return ' + arg + '()');

        console.log(typeof arg, this);
        console.log(func);
        console.log(func());
    } catch (e) {
        console.log(e);
    }
}

function run() {
    function test() {
        console.log('Local test() run.');
    }

    check(test);
    check('test');
}

var r = new run();

http://jsfiddle.net/userdude/7Lz15qou/

run()被调用时,它内部有它自己的范围,它是它自己的本地范围。其中声明的变量和函数都有自己的引用,这些引用只能在function run(){}中看到。

当您传递run(test)时,您通过查找变量的引用来传递变量的值,这使得它可以被理解为副本;如您所见here ,您不会影响最初引用的变量,而是更改它的本地实例*。

这很重要的原因是,如果没有与新作用域中的引用关联的(在您的情况下是函数值),您所拥有的就是与其原始值无关的字符串。无论是否使用 eval(),您都不能调用该范围内未定义的内容;这是不合逻辑的。

这有点像有两个表演环和一个神奇的笼子,其中一个环里有狮子。当您将Lion发送到另一个环ring(Lion)时,您指着笼子并说获取狮子的副本并将其放入在那枚戒指中

当您说ring('Lion')时,您已经告诉另一个环Lion,但没有定义Lion。所以那个戒指到处跑,上面写着狮子!狮子!但是没有狮子,只有一个词。 Lion未定义,因此您得到的不是表演,而是滑稽但错误的结果。人们可能会想要回他们的钱。

这就是为什么您尝试做的事情不起作用。

<小时/>

* 许多语言允许通过引用传递,但 Javascript 不允许。

关于javascript - 通过字符串名称调用 "local"函数而不使用 eval?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25219442/

相关文章:

javascript - javascript 函数调用是否在整个脚本解析完成之前运行?

php - fatal error : Call to undefined function oci_connect() in Wamp

c++ - 回调函数 : difference between void(*func)(int) and void(func)(int)

c++ - 制作一个从函数返回字符串的数字拼写程序

c# - 求值表达式 通用 C# 求值条件 多态性

c# - 如何评估 C# 中可以被零除的字符串表达式?

javascript - 更改responsiveCollapse模型中的默认+/-图标

javascript - 如何使用 document.evaluate() 和 XPath 获取元素列表?

php - 仅当使用 DNS 时,AJAX 请求出现 405(方法不允许)

javascript - Node.js 全局 eval,抛出 ReferenceError