词汇范围问题

时间:2017-09-01 08:40:59

标签: javascript hoisting lexical-scope

我正在阅读这本书' Scope&瓶盖'在系列中你不知道JS'我读到函数先挂起,变量稍后挂起。 浏览此代码段:

function foo() {
    var a = 2;
    function bar() {
        console.log( a ); // 2
    }
    bar();
}
foo();

如果是这种情况,函数bar()是否应该挂到顶部并且此代码应该产生错误?因为在吊装之后,这段代码应该是这样的(至少我理解的)

function foo() {
    function bar() {
        console.log( a );
    }
    var a;
    a = 2;
}

这是因为函数被提升到顶部和后面的变量。如果不是这样,请纠正我。

2 个答案:

答案 0 :(得分:2)

他们都将一直提升到顶部,因此a位于bar的范围内;它的功能不是"以上"变量。订单发挥作用的唯一时间是函数声明和变量具有相同的名称,在这种情况下函数声明获胜,因为当变量被提升时,如果已经存在变量,则不会创建它。现有的具有给定名称的绑定。

"起重"是一个方便的简写术语,但它不是字面的。当foo被称为时会发生什么(留下一些细节以专注于问题中的问题)

  1. 为调用foo
  2. 创建执行上下文
  3. 创建该上下文中的对象以保存"绑定"用于该上下文执行的标识符(如示例中的bara
  4. 处理所有函数声明,并将其标识符的绑定添加到对象中(如果有多个具有相同名称的声明,则最后一个声明获胜)
  5. 处理所有变量声明并将其标识符添加到对象如果对象尚未绑定它们
  6. 然后,该对象用于处理执行上下文中的绑定(例如,在引用a时使用与绑定关联的值,在设置a时设置,等等。)

答案 1 :(得分:0)

hoisting在编译部分完成,bar函数的编译在调用之前不会完成。那么为什么bar应该显示错误。 如果您还想了解有关如何编译或执行javascript的详细信息。这是一段精彩视频https://www.youtube.com/watch?v=QyUFheng6J0