snippet 1 -> output is "b"
if (true) {
x = "b";
function x() {}
}
console.log(x); //b
snippet 2 -> output is ƒ x() {}
if (true) {
function x() {}
x = "b";
}
console.log(x); // ƒ x() {}
I know that using strict mode will not affect the global variable at all, but I want to know how x
is being assigned different values when strict mode is disabled.
See What are the precise semantics of block-level functions in ES6?: the function
declares a local (block-scoped) variable, which the x = 'b'
assignment will overwrite. However, it also exposes the value of that local variable at the point of the function
declaration to the outer scope, creating the global variable that your console.log(x)
after the block observes.
Transforming the code to more explicit let
declarations leads to
// snippet 1
if (true) {
let _x = function x() {}; // hoisted
_x = "b"; // assigns local _x
x = _x; // where the `function` declaration was
}
console.log(x); // b
and
// snippet 2
if (true) {
let _x = function x() {}; // hoisted
x = _x; // where the `function` declaration was
_x = "b"; // assigns local _x
}
console.log(x); // ƒ x() {}