尽管存在全局范围变量,为什么在第一个控制台日志中执行失败
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中的变量将被提升。这意味着即使您稍后在代码中声明它们,它们仍然可以在早期调用中访问:它就像声明(不是值的赋值!)将被写在块的第一行中已经宣布了。
在你的代码中,你已经在函数体中声明了你的message
变量,所以它试图访问那个因为提升而不是在全局范围内声明的那个。
关于此事的更多阅读here
因为在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();