0

Consider the following coding snippet :-

console.log(a); //undefined
{
    function a() {}
    console.log("Global", window.a, "Block", a); //Global ƒ a() {} Block ƒ a() {}
    a = 1;
    console.log("Global", window.a, "Block", a); //Global ƒ a() {} Block 1
    a = 3;
    console.log("Global", window.a, "Block", a); //Global ƒ a() {} Block 3
    function a() {}
    console.log("Global", window.a, "Block", a); //Global 3 Block 3
    a = 2;
    console.log("Global", window.a, "Block", a); //Global 3 Block 2
}
console.log(a); //3

I came across this when I was figuring out what happens when I declare a function inside a block and I came to know that the block-level function's name will be registered in the global area with a value of undefined. But this value will change once the function declaration is encountered. And I accepted this as is.

But when I extended this example according to a previously seen snippet, it starts acting a bit weird. So here is whats happening and why I can't wrap my head around it.

  • When the execution is on the first line, a in global is undefined.
  • Inside the block, global a is assigned the function on the first line of block. Also, a local variable is created with the function as its value.
  • Now we reassign the value of 1 to a. This changes only the local variable's values and not the global variable.
  • Same thing happens with the value 3. All good so far.
  • Now the function is re-declared and that doesn't affect the local variable, but it does change the value of the global variable to the value of local a. Why? And even if it has to change the value to something new, it should have been the function and not 3.
  • On the next line the same thing happens as in case of 1 and 3.

So this is what I am confused about. I couldn't find any proper and simple explanation about the block-level functions so I can't understand whats happening here.


I understand than there is an explanation in this question about the block-level function. But even after considering that, its not clear why the function's re-declaration is affecting the global value but not the local value. So please answer that part of my question. Also I know that strict mode will solve this issue but I just want to understand why it behaves so in sloppy mode.

Jay Mehta
  • 13
  • 3
  • 3
    Yes, it is weird. To avoid the weirdness, always use strict mode! – Bergi Apr 17 '23 at 11:55
  • The re-declaration is equivalent to the assignment of the (for compatibility reasons implicitly declared) block-scoped variable to the hoisted function-scoped variable. The function is only declared once (at the top of the block) due to hoisting. See [this answer](https://stackoverflow.com/a/31461615/13561410) for reference, it should include all relevant information. – Oskar Grosser Apr 17 '23 at 14:28
  • "*Its not clear why the function's re-declaration is affecting the global value but not the local value*" - it is due to the `compat₀ = compat₁;` assignment, which happens when the function statement is evaluated, and which assigns the local variable value to the global variable. Notice that it does not distinguish between the "first" declaration and the "redeclaration", both work in the same manner. In the first occurrence, the local variable has the function value, in the second occurrence, the local variable has the value `3`. – Bergi Apr 17 '23 at 16:52
  • It might help to add another `console.log` line *before* the first declaration statement. – Bergi Apr 17 '23 at 16:53

0 Answers0