我使用jQuery,我需要使用eval()函数生成一个匿名方法。
以下几行适用于Opera,但不适用于IE,FF,Chrome:
var callbackStr = "function(){alert('asdf');}";
var callback = eval(callbackStr);
callback();
此代码适用于所有浏览器:
var callbackStr = "var callback = function(){alert('asdf');}";
eval(callbackStr);
callback();
你知道,我已经解决了我的问题。但我想知道,到底发生了什么。任何人都可以向我解释这种行为,或告诉我在哪里可以找到更多信息吗?
(PS:我知道this page。)
答案 0 :(得分:6)
原因与您在使用eval
之前围绕JSON字符串括起括号的原因相同 - eval将 eval假定匿名函数是FunctionDeclaration。使用括号允许eval将内部处理为表达式:{
视为令牌,即语句的开头
var callbackStr = "(function(){alert('asdf');})";
var callback = eval(callbackStr);
callback();
// -> alerts 'asdf';
至于为什么Opera在这里行为不同,我不知道。至于你对eval
的使用,可能有更好的方法(几乎总是如此)。
我在ECMA-262 3rd Edition的第12.4节中为你挖出了一个引用的引用:
请注意,ExpressionStatement不能以开括号大括号开头,因为它可能会成为一个大括号 与块模糊不清。 另外,ExpressionStatement不能以function关键字开头,因为 这可能会使FunctionDeclaration 模糊不清。
强调我的。
答案 1 :(得分:2)
如果你像这样做你的eval,第一个例子就可以了。
var callbackStr = "function(){alert('asdf');}";
var callback = eval("(" + callbackStr + ")");
callback();
答案 2 :(得分:1)
eval
不会返回这样的函数。相反,它在全局范围内执行一段代码,这就是第二个示例的工作原理 - callback
var已在全局范围内创建。
我确信这些只是极其简化的示例,但您几乎总是可以避免首先使用eval,这是推荐的。
答案 3 :(得分:-1)
第一种情况只是评估你的字符串并执行该函数。它不会返回指向该特定函数的指针,这就是您无法通过调用回调来执行它的原因。