根据MDN-EVAL
您不能通过eval()以外的名称调用eval函数来间接使用eval函数;如果这样做,可能会发生运行时错误。例如,您不应使用以下代码:
var x = 2; //1
var y = 4; //2
var myEval = eval; //3
eval("x + y"); //4
myEval("x + y"); //5
正常情况JavaScript不会考虑var someReference = someFunctionReference;
,但是eval是特殊情况,所以我可以期待一些惊喜。
现在让我们看一下非严格模式下的一些运行
现在我的查询是为什么会有不同的行为以及这种编码方式在何时/何时会给我的程序带来风险。
P.S。:x
行不会在任何运行中抱怨任何错误。我在上面的运行中假设chrome / firefox控制台以非严格模式运行。
答案 0 :(得分:1)
eval
很特别。从ES5(~2009)开始,对eval
的直接调用在当前作用域内有效,但间接调用它与myEval
一样适用于全局作用域。详情请参阅§10.4.2和§15.1.2.1.1。
因此,如果您的代码在函数中运行,例如:
function foo() {
var x = 2;
var y = 4;
var myEval = eval;
myEval("x + y");
}
...然后正确的行为,因为ES5会抱怨x
不存在。
如果您的代码在所有函数之外的全局范围内,例如:
var x = 2;
var y = 4;
var myEval = eval;
myEval("x + y");
...然后正确的行为是获得结果6
。完整的例子如下。
现在我的查询是为什么有不同的行为...
如果您在浏览器控制台中运行该代码,则可能是控制台实现(例如,一个控制台可能会评估您在函数中的代码,另一个控制台在全局范围内)。控制台是一个特殊的环境,与此相关的范围相关的东西最好用普通页面进行测试。
以及如何/何时执行此编码风格会给我的程序带来风险。
直接或间接使用eval
的风险没有显着差异。风险来自于对您无法控制的输入使用eval
(根本)。如果您正在从用户那里获取输入并立即在他们的计算机上运行,则风险主要在于他们。但是,如果您从一个用户那里获取输入,然后通过另一个用户的计算机或服务器上的eval
运行,则存在重大风险:您允许该用户伸出并在不属于他们的机器上运行代码。
P.S。:我在上面的假设中运行chrome / firefox控制台以非严格模式运行。
严格模式不会影响eval
的这个方面。 (它 影响它的其他方面,特别是它是否可以在局部范围内创建变量[它可以在松散模式下,它不能在严格模式下];这也在§10.4.2中。)
直播示例:
function direct() {
var x = 2;
var y = 4;
return eval("x + y");
}
function indirect() {
var x = 2;
var y = 4;
var myEval = eval;
return myEval("x + y");
}
snippet.log("Direct (within function):");
try {
snippet.log("Got " + direct());
}
catch (e) {
snippet.log("Got exception: " + e.message);
}
snippet.log("Indirect (within function):");
try {
snippet.log("Got " + indirect());
}
catch (e) {
snippet.log("Got exception: " + e.message);
}
var globalX = 2;
var globalY = 4;
snippet.log("Direct (at global scope):");
try {
snippet.log("Got " + eval("globalX + globalY"));
}
catch (e) {
snippet.log("Got exception: " + e.message);
}
snippet.log("Indirect (at global scope):");
var myGlobalEval = eval;
try {
snippet.log("Got " + myGlobalEval("globalX + globalY"));
}
catch (e) {
snippet.log("Got exception: " + e.message);
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
正确的行为是:
Direct (within function): Got 6 Indirect (within function): Got exception: x is not defined Direct (at global scope): Got 6 Indirect (at global scope): Got 6