使用eval执行函数 [英] Using eval to execute functions

查看:273
本文介绍了使用eval执行函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于eval如何工作,我有些不明白的事情。
假设我有一个函数foo:

There is something I don't understand about how eval works. Suppose I have a function foo:

function foo() {
    console.log("test");
}

然后我写

eval("foo()");

eval("foo" + "();");

执行函数foo并打印出test。
但是,如果我写:

The function foo is executed and I have "test" printed out. However, if I write:

eval("function foo() { console.log(\"foo\"); }();");

eval("function foo() { console.log(\"foo\"); }" + "();");

我得到SyntaxError:Unexpected token。
为什么?我看到当我传递函数名时,它被计算到函数的代码中,所以我认为它应该与eval(foo+(););

I get "SyntaxError: Unexpected token )". Why is that? I saw that when I pass the function name it is evaluated into the function's code, so I though it's supposed to be the same as "eval("foo" + "();");"

我使用的是Chrome 27,如果它有任何区别。

I'm using Chrome 27 if it makes any difference.

推荐答案

因为答案没有具体说明为什么最后一个代码段失败,似乎没有人警告你 eval 的危险:

Because no answer is specific about why the last snippet fails, and nobody seems to be warning you for the dangers of eval:

eval ,根据 MDN


表示JavaScript表达式,语句或语句序列的字符串。表达式可以包含现有对象的变量和属性。

A string representing a JavaScript expression, statement, or sequence of statements. The expression can include variables and properties of existing objects.

你的字符串,function foo(){console .log('foo');}()实际上由2个语句组成,对JS引擎没有任何意义。好吧,第二个没有:

Your string, "function foo(){console.log('foo');}()" actually consists of 2 statements, that make no sense to the JS engine. Well, the second one doesn't:

function foo(){console.log('foo');}//function declaration, fine
;//<-- js adds implied statement terminator
()//no invocation, because no function reference, group nothing ==> does not compute, raise error

这就是你拥有来改变你的功能的原因声明语句到表达式中,通过添加运算符。通常,这是分组运算符:()

That's why you have to turn your function declaration statement into an expression, by adding an operator. Typically, this is the grouping operator: ()

(function foo(){ console.log('foo')});

函数声明现在是一个表达式,所有内容(分组() included)可以看作是一个语句,除非后面的代码属于上面的代码。在这种情况下,调用括号显然会这样做,所以JS引擎会为你排序。

为清楚起见,有人说首选表示法是:

The function declaration is now an expression, everything (the grouping () included) can be seen as a statement, unless the code that follows belongs to the code above. In this case, the invoking parentheses clearly do, so the JS engine sorts it out for you.
For clarity, some say the preferred notation is:

(function f(){}());//<-- invoking parentheses inside group

这是有道理的,因为调用毕竟是声明的一部分。

Which makes sense, because the invocation is part of the statement, after all.

如果你不喜欢所有这些括号,任何运算符都会这样做:

If you don't like all these parentheses, any operator will do:

~function(){}();//bitwise not
+function(){}();//coerce to number

都是同等有效的。请注意,它们更改函数表达式的可能返回值。

Are all equally valid. Note that they will change the possible return values of the function expression.

(function(){}());//resolves to undefined
+function(){}();//resolves to NaN, because undefined is NotANumber

你的 eval如何看起来可能是以下任何一种:

How your eval could look, then, is any of the following:

eval("(function (){console.log('foo');}());");
eval("~function (){console.log('foo');}();");
eval("!function (){console.log('foo');}();");

以此类推......等等......

And so on, and so forth...

最后, eval 评估全局范围内的代码,因此包含函数的任何代码 eval -ed都可以,并且很可能会对全局命名空间进行规范。恶意代码也可以访问所有,所以要厌倦XSS攻击和所有其他基于JS的技术。

底线, eval evil ,特别是因为所有浏览器现在都支持 JSON.parse 本地,而对于那些不支持 JSON.parse 的人来说,仍然存在尝试并测试了JSON2.js文件。

在严格模式下使用 eval 确实使事情稍微安全一些,但不会阻止XSS攻击例如,代码仍然可以操纵DOM,并重新分配暴露的DOM引用或对象。

Lastly, eval evaluates code in the global scope, so any code eval-ed containing functions can, and likely will, polute the global namespace. Mallicious code will also have access to everything, so be weary of XSS attacks and all other JS based techniques.
Bottom line, eval is evil, especially since all browsers now support JSON.parse natively, and for those that don't, there still is a tried and tested JSON2.js file out there.
Using eval in strict mode does make things slightly safer, but doesn't prevent XSS attacks at all, the code can still manipulate the DOM, for example, and reassign exposed DOM references or objects.

Google 为什么eval是邪恶的如果你想了解更多信息。

另外检查 ECMAScript 规范

Google "why eval is evil" if you want to find out more.
Also check the ECMAScript specs

这篇关于使用eval执行函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆