变量全局作用域,但为什么函数无法访问?

问题描述 投票:1回答:2

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

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在这个特定函数的开头不能访问全局变量。

请轻松一点。谢谢

javascript scope global-variables
2个回答
1
投票

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

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

关于此事的更多阅读here


3
投票

因为在message中对scopeTest的任何引用都将引用最近的范围,其中声明了message变量 - 也就是说,在scopeTest函数内部。在您尝试引用它时,message已被识别为函数内部的变量名称(也就是说,当您引用它时,您引用的是局部变量,而不是全局变量),但是局部变量具有尚未初始化 - 解释器没有穿过const message =线,因此非军事区或时间死区中的message变量 - 在初始化之前尝试引用它将导致错误,它未被定义。

如果从const message中删除scopeTest(以便引用message变量名称将引用全局变量),或将const message移动到test #1之上(以便在您尝试记录它时初始化它),它将会按预期工作:

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();
© www.soinside.com 2019 - 2024. All rights reserved.