gpt4 book ai didi

javascript - 使用 eval 执行函数

转载 作者:行者123 更新时间:2023-11-28 15:59:38 28 4
gpt4 key购买 nike

我不明白 eval 的工作原理。假设我有一个函数 foo:

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

然后我写

eval("foo()");

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

函数 foo 被执行,并且我打印出了“test”。但是,如果我写:

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

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

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

如果有什么不同的话,我正在使用 Chrome 27。

最佳答案

因为没有具体答案为什么最后一个片段失败,并且似乎没有人警告您eval的危险:

评估,根据MDN :

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引擎来说毫无意义。嗯,第二个没有:

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

这就是为什么您必须通过添加运算符将函数声明语句转换为表达式。通常,这是分组运算符:()

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

函数声明现在是一个表达式,所有内容(包括分组())都可以被视为一条语句,除非后面的代码属于上面的代码。在这种情况下,调用括号显然是这样做的,因此 JS 引擎会为您进行排序。
为了清楚起见,有人说首选符号是:

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

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

如果您不喜欢所有这些括号,任何运算符都可以:

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

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

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

那么,您的 eval 的外观可能是以下任意一种:

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

等等,等等......

最后,eval 在全局范围内计算代码,因此任何包含函数 eval 的代码都可能并且很可能会污染全局命名空间。恶意代码还可以访问一切,因此请警惕 XSS 攻击和所有其他基于 JS 的技术。
底线是,eval邪恶,特别是因为所有浏览器现在都原生支持JSON.parse,而对于那些不支持的浏览器,仍然有一个经过尝试和测试的 JSON2.js 文件。
在严格模式下使用 eval 确实使事情变得更安全,但根本无法防止 XSS 攻击,例如,代码仍然可以操作 DOM,并重新分配暴露的 DOM 引用或对象。

如果您想了解更多信息,请搜索“为什么 eval 是邪恶的”。
另外check the ECMAScript specs

关于javascript - 使用 eval 执行函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17447256/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com