在Safari中评估表达式const变量范围

时间:2017-09-04 12:21:40

标签: javascript exception scope safari eval

很高兴知道为什么这个表达式:

eval("const a = function () {}; function b() {  a(); }; b();")

在Safari 10.1.2中运行时抛出错误:

  

ReferenceError:找不到变量:a

1 个答案:

答案 0 :(得分:3)

我怀疑使用const(或let)将此变量放入某个内部eval的范围内,而eval内部调用的函数正在使用:

  1. 全局范围,如果它们由function X(){};
  2. 定义
  3. 内部范围,如果它们被定义为const X = function(){}
  4. 例如,使用const

    > eval('const a = function(){ return 42; }; a();')
    42
    > a
    ReferenceError: Can't find variable: a
    

    使用var

    > eval('var a = function(){ return 42; }; a();')
    42
    > a
    function (){ return 42; }
    

    支持这一理论:

    > eval('const a=function(){return 42;}; const b=function(){return a();}; b();')
    42
    > a
    ReferenceError: Can't find variable: a
    > b
    ReferenceError: Can't find variable: b
    

    因此,如果我们以相同的方式定义两个函数,它就有效。

    现在,让我们在全局范围内定义函数a,而不使用eval

    > a = function(){ return 23;}
    

    让我们从您的问题中运行eval代码(将return添加到这两个函数中):

    > eval("const a = function(){return 42;}; function b(){return a();}; b();")
    23
    

    如您所见,函数b正在使用全局范围内的a