【问题标题】:Variable globally scoped but why function unable to access?全局范围的变量,但为什么函数无法访问?
【发布时间】:2023-03-20 16:03:02
【问题描述】:

尽管存在全局范围的变量,为什么在第一个控制台日志中执行失败?

const message = 'starts with mssg #1'; //Global scope

function scopeTest() {
  console.log('1. test #1: ', message); // <-- why unable to read Global scope here?

  const message = 'changed to mssg #2';
  console.log('2. test #2: ', message);

  if (true) { //Code block is OK
    const message = 'changed to mssg #3';
    console.log('3. test #3: ', message);
  }

  { //Another code block is OK
    const message = 'changed to mssg #4';
    console.log('4. test #4: ', message);
  }

  console.log('5. test last: ', message);
}
scopeTest();

不需要替代编码解决方案。只是想了解为什么 JS 不能在这个特定函数的开头访问全局变量。

请解释一下。谢谢

【问题讨论】:

  • 因为const is hoisted in its scope,本地message 会影响全局。
  • FF 中更有用的错误信息:“message”:“ReferenceError: can't access lexical declaration `message' before initialization”

标签: javascript scope global-variables


【解决方案1】:

因为在scopeTest 内对message 的任何引用都将引用声明了message 变量的最近范围 - 即在scopeTest 函数内。在您尝试引用它时,message 已被标识为一个变量名在函数内部(也就是说,当您引用它时,您引用的是局部变量,而不是全局变量),但局部变量尚未初始化 - 解释器尚未运行 const message = 行,因此非军事区或临时死区中的 message 变量 - 试图在之前引用它已经初始化了会报未定义的错误。

如果您从scopeTest 中删除const message(这样对message 变量名的引用将引用全局变量),或者将const message 移动到上方 @ 987654332@(以便在您尝试记录时初始化),它将按预期工作:

const message = 'starts with mssg #1'; //Global scope

function scopeTest() {
  const message = 'changed to mssg #2';
  console.log('1. test #1: ', message);
}
scopeTest();

和

const message = 'starts with mssg #1'; //Global scope

function scopeTest() {
  console.log('1. test #1: ', message);
}
scopeTest();

【讨论】:

    【解决方案2】:

    JavaScript 中的变量在声明时被提升。这意味着即使您稍后在代码中声明它们,它们仍然可以在之前的调用中访问:就像声明(而不是值的分配!)将被写入您所在块的第一行已经宣布了。

    在您的代码中,您已经在函数体中声明了您的message 变量,因此它试图访问 那个 变量,因为提升,而不是在全局范围内声明的变量。

    更多关于此事的阅读here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      • 2016-08-19
      • 1970-01-01
      • 2011-07-23
      相关资源
      最近更新 更多