Javascript eval别名

sim*_*ack 6 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>
Run Code Online (Sandbox Code Playgroud)

Col*_*son 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中所述的声明绑定实例化.

  • 你误读了这个标准.`eval`*可以*别名,但它会以不同的方式工作.请参阅标准的其他部分:"*Eval代码是提供给**内置eval函数的源文本.***"(#10.1),"*或者如果eval代码没有被*评估*直接致电***"(#10.4.2)和其他人. (3认同)
  • 如果“eval”不是函数,为什么“alert(eval)”显示“function eval() { [native code] }”? (2认同)