【问题标题】:Why I cannot access this variable inside this simple function?为什么我不能在这个简单的函数中访问这个变量?
【发布时间】:2020-12-28 10:42:46
【问题描述】:

我是 Javascript 新手,我不明白范围在以下代码中是如何工作的:

//Code n°1:

let num = 1;

function test(){
    console.log(num);
}

test()       //As I expected I get in console "1"
//Code n°2:

let num = 1;

function test(){
    let num = 2;
    console.log(num);
}

test()       //As I expected I get in console "2"

但问题来了:

//Code n°3:

let num = 1;

function test(){
    console.log(num)
    let num = 2;
    console.log(num);
}

test()       //I expected to get in console "1" and then "2" but instead I get an error.

当我在浏览器中运行代码 n° 3 时,我收到此错误: 未捕获的 ReferenceError:无法在初始化之前访问词法声明 'num'

如果我查看代码 1 和 2,我想在运行代码 3 后,我会在控制台中输入数字 1,然后是数字 2。但这并没有发生。为什么?

非常感谢!

【问题讨论】:

  • 我认为它被称为临时死区 - 我假设你知道 var 不会发生这种情况 - 我还假设你知道如何提升 var 声明 - 没有这样的提升 let (或const )
  • 我原以为错误是关于重新声明 num。相反,错误是关于在初始化之前访问num,如果不深入了解 JavaScript 的解释方式,这是没有意义的,我没有。

标签: javascript function variables scope let


【解决方案1】:

当词法变量在初始化之前被访问时,会发生 JavaScript 异常“在初始化之前无法访问词法声明‘变量’”。这发生在任何块语句中,当 let 或 const 声明在定义之前被访问时。

【讨论】:

  • 我无法在上面发表评论,但您需要删除导致重新声明的 let。这在 javascript 中是不允许的。代码 2 正在工作,因为变量的重新声明不会发生在函数内部。第一个实例在它之外,然后你在函数内部更改它的值,这很正常。
【解决方案2】:

当“测试函数”被调用时,函数体被执行。当它到达'console.log(num)' 时,它开始在测试函数范围内搜索'num 变量声明'(或'num assignment'或'num reassignment)。所以它在下一行找到变量声明。搜索变量的优先级是:

  1. 当前范围
  2. 关闭
  3. 作用域链

所以,当在当前作用域中找到变量声明时,搜索不会继续作用域链。 (它不会在全局范围内搜索 num 变量。)

我猜这是错误的原因,但由于我是 javaScript 的新手,我并不完全确定。

【讨论】:

    【解决方案3】:

    如果你初始化变量没有重新声明,它会正常工作,现在如果你重新声明变量,那么这个错误会发生在letvar,因为在同一个作用域中,它被前面的console.log()调用。 不建议你重新声明 let 变量,如果需要,不要在前面的语句中使用相同的,注意如果你注释了第一个 console.log() ,代码将再次工作,这恰好发生在此范围内的变量的生命周期内,在这种情况下,let

    let num = 1;
    
    function test(){
    
        console.log(num)
        let num = 2;
        console.log(num);
    }
    
    test()
    

    【讨论】:

      【解决方案4】:

      因为在 javascript 中用 var 声明的函数和变量被提升,移动到函数/词法块的顶部。

      但是让关键字尊重词法流。它在声明它的地方固定变量。

      console.log 尝试访问在流程中声明的变量。 因此,手动将您的 let 声明向上移动到 de console.log 之上或将其更改为 var let num = 2;让javascript引擎自动移动它。

      var num = 1;
      
      function test(){
          let num = 2;
          console.log(num);
      }
      
      test() 
      

      var num = 1;
      
      function test(){
          console.log(num)
          var num = 2;
          console.log(num);
      }
      
      test() 
      

      或者,访问全局 var num,它被测试主体的声明所遮蔽,var 或 let,不管

      var num = 1;
      
      function test(){
          console.log(num)
          //let num = 2;
          console.log(num);
      }
      
      test() 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-22
        • 1970-01-01
        • 1970-01-01
        • 2017-12-30
        相关资源
        最近更新 更多