【问题标题】:Hoisting vs Scope Chain [duplicate]提升与范围链 [重复]
【发布时间】:2022-01-08 14:55:21
【问题描述】:

为什么,在第一段代码中,我得到了“Hello”,但在第二段代码中,我得到了 undefined,然后是“bye”?

对于第一个代码块,我知道它正在沿着作用域链向上获取提升的变量“Hello”,我得到了预期的结果。

    var greet = "Hello";

    var sayHi = () => {
        console.log(greet);
    }

    sayHi();

但是,我很难理解,如果我在 console.log 的第一个实例之后声明变量 greet,我首先得到未定义? JS引擎不应该先上作用域链找到“Hello”吗?

        var greet = "Hello";

    var sayHi = () => {
        console.log(greet);

        var greet = "Bye"; 
        console.log(greet);
    }

    sayHi();

【问题讨论】:

  • 它没有上升,因为它已经在当前范围内找到了greet(你声明的第二个,它被提升了)。当时还是undefined。如果您使用 let/const 而不是 var(您通常应该这样做),则在其 TDZ 内访问时会出错。
  • 因为您在第二个sayHi 函数中使用的greet 是该函数中的一个本地,因为您已经使用var 声明了它,它被提升到函数的顶部——但只有声明,而不是赋值,所以你从 greet 开始,其值为 undefined

标签: javascript environment-variables scoping hoisting


【解决方案1】:

声明和初始化是有区别的。声明创建变量,初始化为其分配初始值。声明 var greet = "Bye"; 包含这两个东西,但只有声明被提升。

【讨论】:

  • 这是前面问题和答案中充分覆盖的基础,无需添加更多。
【解决方案2】:

在提升后的第二个block中,执行如下。这就是为什么你会看到undefined,然后是Bye

var greet = "Hello";

    var sayHi = () => {
        var greet;
        console.log(greet);

        greet = "Bye"; 
        console.log(greet);
    }

    sayHi();

在函数中,它看到greet 变量在其范围内定义。它不会像您期望的那样在作用域链中查找。

【讨论】:

  • 这是前面问题和答案中充分覆盖的基础,无需添加更多。
猜你喜欢
  • 1970-01-01
  • 2013-03-22
  • 2011-11-28
  • 2011-09-30
  • 2021-03-22
  • 1970-01-01
  • 2016-02-24
  • 2017-07-18
  • 1970-01-01
相关资源
最近更新 更多