2

可能重复:
为什么使用 JavaScript eval 函数是个坏主意?

因此,我已经阅读了许多不同的方法来从字符串调用函数,使用window[]();eval();. 我想知道对于我的情况(如下),哪种方法是正确的方法,如果是,请解释原因。还要解释为什么eval();这不是一个好的选择,很多人说安全,但是如果您可以获得任何能够让您更改该页面上的脚本的浏览器插件,为什么安全会成为一个问题?(例如:火狐的萤火虫)

我当前的代码:

funcOne(target).funcTwo(x, y, z);

如何使用推荐的window[]();方式调用它?为什么我不能使用这个?:

eval('funcOne(target).funcTwo(x, y, z)');

我不希望你多次被问到这个问题而烦恼,因为我目前想不出一种方法来调用一个调用它的双重函数。

提前致谢!

4

1 回答 1

6

在 Javascript 中,语法a.b可以替换为a["b"]. 所以在你的情况下你可以使用

window["funcOne"](target)["funcTwo"](x, y, z);

"funcOne"当然,只有在使用变量而不是and时才有意义"funcTwo"

如果一切都是固定的,但您只是想延迟执行,您可以使用带有匿名闭包的“thunking”

x = function(){ return funcOne(target).funcTwo(x, y, z); };

然后您可以评估 withx()以在以后获得所需的结果。

即使变量targetand和是封闭范围的本地变量,最后一个示例也将正常工作,因为 thunking 闭包将“捕获”它们xyz

但是,您应该注意这样一个事实,即在 Javascript 中创建新范围的唯一方法是使用函数(一个被包围的块,{}不是像 C++ 和其他语言中那样的范围)。

如果你需要在一个循环中创建几个闭包,这可能会反击,并且是一个非常常见的错误的根源......

for (var i=0; i<options.length; i++)
{
    var menu_item = document.createElement("div");
    menu_item.textContent = "Option " + i;
    menu_item.onclick = function () {
        // Warning this will NOT work. All divs will
        // alert using the same number!
        alert("Option " + i + " selected");
    }
    menu.appendChild(menu_item);
}

在这里,我为 div 上的事件使用了一个闭包onclick,但这不起作用,因为所有这些函数都将使用相同的i变量。因为在 Javascript 中创建作用域的唯一方法是使用函数,所以解决方案是:

for (var i=0; i<options.length; i++)
{
    var menu_item = document.createElement("div");
    menu_item.textContent = "Option " + i;
    (function(i){
         menu_item.onclick = function () {
             alert("Option " + i + " selected");
         };
     })(i); // Pass current `i` as parameter
    menu.appendChild(menu_item);
}

这样,处理程序中的变量i对于onclick每个闭包都是不同的。

当您需要创建许多独立的闭包时,这种创建函数只是为了立即调用它的模式通常在 Javascript 中使用,因此最好了解和理解它。

于 2012-10-21T08:32:56.827 回答