Javascript eval别名

时间:2013-07-21 09:10:49

标签: javascript

javascript是否允许别名评估? 以下代码的第一部分意外行为(显示1,1),但第二部分不行(显示1,2)。 对ECMA脚本或mozilla文档的引用会很有帮助,我找不到。

<html>
<script type="application/javascript;version=1.8">
    (function(){
        eval('var testVar=1');
        alert(testVar);
        var eval2=eval;
        eval2('var testVar=2');
        alert(testVar);
    })();

    (function(){
        eval('var testVar=1');
        alert(testVar);
        eval('var testVar=2');
        alert(testVar);
    })();
</script>
</html>

2 个答案:

答案 0 :(得分:7)

您不能“别名”eval并期望它的行为相同。就那么简单。为什么? eval不是函数。

当您调用eval2时,您正在设置变量“cache”以使用全局变量。因此,通过在其中设置变量,您将设置全局变量。但是,在退出时,变量“cache”返回到函数作用域。这就是第二个alert显示1的原因 - 全局变量被函数级别1遮蔽。

这在ECMAScript(强调我的)附件E(第239页)中有说明

  

10.4.2:在第5版中,对eval函数的间接调用使用全局环境作为变量环境和eval代码的词法环境。在第3版中,间接eval的调用者的变量和词法环境被用作eval代码的环境。

“输入评估代码”的完整定义在§10.5.2(第58页)中定义(强调我的)

  1. 如果没有调用上下文,或如果eval代码没有被直接调用(15.1.2.1.1)评估到eval函数那么,
    • 将执行上下文初始化为好像是全局执行上下文,使用eval代码作为C,如10.4.1.1中所述。
  2. 否则,
    • 将ThisBinding设置为与调用执行上下文的ThisBinding相同的值。
    • 将LexicalEnvironment设置为与调用执行的LexicalEnvironment相同的值 上下文。
    • 将VariableEnvironment设置为与调用执行的VariableEnvironment相同的值 上下文。
  3. 如果eval代码是严格的代码,那么
    • 让strictVarEnv成为调用NewDeclarativeEnvironment传递LexicalEnvironment作为参数的结果。
    • 将LexicalEnvironment设置为strictVarEnv。
    • 将VariableEnvironment设置为strictVarEnv。
  4. 使用eval代码执行声明绑定实例化,如10.5中所述。

答案 1 :(得分:2)

在第一种使用eval的情况下,它使用执行它的函数作用域。当您将eval分配给eval2然后执行相同的语句时,它似乎使用window上下文(全局范围)而不是函数上下文。这就是为什么你在第一种情况下看到相同的值1,因为函数内的testVar是1而window.testVar外面是2.你可以通过执行下面的代码片段来证明这一点

<script>
(function(){
        eval('var testVar=1');
        alert(window.testVar);
        var eval2=eval;

        eval2('var testVar=2');
        alert(window.testVar);
    })();

    (function(){
        eval('var testVar=1');
        alert(testVar);
        eval('var testVar=2');
        alert(testVar);
    })();
</script>

实际上,根据Mozilla Developer Network,您不能为eval添加别名。