bg27
bg27

Reputation: 47

Variable globally scoped but why function unable to access?

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

Answers (2)

Davide Vitali
Davide Vitali

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

CertainPerformance
CertainPerformance

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

Related Questions