Reputation: 47
Why execution failed at first console log despite globally scoped variable exist?
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();
Alternative coding solution not required. Just wanted to understand why JS can't access the global variable at the start of this particular function.
Please shed light. Thank you
Upvotes: 1
Views: 87
Reputation: 1035
Variables in JavaScript are hoisted when declared. This means that even if you declare them later in the code, they will still be accessible in earlier calls: it is like the declaration (not the assignation of the value!) would’ve been written in the first line of the block where you’ve declared it.
In your code, you have declared your message
variable in the body of the function so it is trying to access that one because of hoisting, instead of the one declared in the global scope.
More reading on the matter here
Upvotes: 1
Reputation: 370769
Because any references to message
inside scopeTest
will refer to the nearest scope which has a message
variable declared - that is, inside the scopeTest
function here. At the time you try to reference it, message
has been identified as a variable name scoped inside of the function (that is, when you reference it, you're referencing the local variable, not the global variable), but the local variable has not been initialized yet - the interpreter hasn't run across the const message =
line, so the message
variable in in the demilitarized zone, or the temporal dead zone - trying to reference it before it has been initialized will result in the error that it's not defined.
If you remove the const message
from inside scopeTest
(so that references to the message
variable name will refer to the global variable), or move const message
to above the test #1
(so that it's initialized by the time you try to log it), it'll work as expected:
const message = 'starts with mssg #1'; //Global scope
function scopeTest() {
const message = 'changed to mssg #2';
console.log('1. test #1: ', message);
}
scopeTest();
and
const message = 'starts with mssg #1'; //Global scope
function scopeTest() {
console.log('1. test #1: ', message);
}
scopeTest();
Upvotes: 3