使用“eval”创建匿名方法- 浏览器特定行为

发布于 2024-09-09 09:31:29 字数 497 浏览 2 评论 0原文

我使用 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:我知道此页面。)

I working with jQuery and i needed to generate an anonymous method with the eval() function.

The following lines worked with Opera but not with IE, FF, Chrome:

var callbackStr = "function(){alert('asdf');}";  
var callback = eval(callbackStr);  
callback();

This code works with all Browsers:

var callbackStr = "var callback = function(){alert('asdf');}";  
eval(callbackStr);  
callback();  

You see, I already solved my problem. But I want to know, what exactly is happening. Can anybody explain this behaviour to me, or tell me where i can find further information?

(PS: I know this page.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

懒的傷心 2024-09-16 09:31:29

原因与在对 JSON 字符串使用 eval 之前需要将括号括起来的原因相同 - eval 将 { 视为令牌,即语句 eval 假定匿名函数是 FunctionDeclaration。使用括号允许 eval 将里面的内容视为表达式:

var callbackStr = "(function(){alert('asdf');})";  
var callback = eval(callbackStr);  
callback();
// -> alerts 'asdf';

至于为什么 Opera 在这里表现不同,我不知道。至于您对 eval 的使用,可能有更好的方法(几乎总是有)。

我为您从规范中引用了 ECMA-262 第三版 的第 12.4 节:

请注意,ExpressionStatement 不能以左花括号开头,因为这可能会使它
与 Block 不明确。 此外,ExpressionStatement 不能以 function 关键字开头,因为
这可能会使 FunctionDeclaration 变得不明确

强调我的。

The reason is the same as the reason you need to wrap parentheses around JSON strings before using eval on them - eval treats { as a token, the start of a statement eval assumes the anonymous functions is a FunctionDeclaration. Using parentheses allows eval to treat what's inside as an expression:

var callbackStr = "(function(){alert('asdf');})";  
var callback = eval(callbackStr);  
callback();
// -> alerts 'asdf';

As for why Opera behaves differently here, I have no idea. As for your use of eval, there's probably a better way (there nearly always is).

I dug out a quote from the spec for you, section 12.4 of ECMA-262 3rd Edition:

Note that an ExpressionStatement cannot start with an opening curly brace because that might make it
ambiguous with a Block. Also, an ExpressionStatement cannot start with the function keyword because
that might make it ambiguous with a FunctionDeclaration
.

Emphasis mine.

怪异←思 2024-09-16 09:31:29

如果您像这样进行评估,第一个示例将会起作用

var callbackStr = "function(){alert('asdf');}";  
var callback = eval("(" + callbackStr + ")");  
callback();

the first example will work if you'll do your eval like this

var callbackStr = "function(){alert('asdf');}";  
var callback = eval("(" + callbackStr + ")");  
callback();
浮世清欢 2024-09-16 09:31:29

eval 不会返回这样的函数。相反,它在全局范围内执行一段代码,这就是第二个示例起作用的原因 - 回调变量已在全局范围内创建。

我确信这些只是极其简化的示例,但您几乎总是可以首先避免使用 eval,这是推荐的。

eval does not return the function like that. Instead it executes a piece of code in the global scope, thats why the second example works - the callback var has been created in the global scope.

I'm sure these are just extremely simplified examples but you can almost always avoid using eval in the first place, which is recommended.

骑趴 2024-09-16 09:31:29

第一种情况只是评估您的字符串并执行该函数。它不会返回指向该特定函数的指针,这就是为什么您不能通过调用回调来执行它。

The first case simply evaluates your string and executes the function. It does not return a pointer to that particular function, that's why you cannot execute it by calling callback.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文