From MDN:
In ECMAScript 2015, let bindings are not subject to Variable Hoisting, which means that let declarations do not move to the top of the current execution context. Referencing the variable in the block before the initialization results in a ReferenceError (contrary to a variable declared with var, which will just have the undefined value). The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.
The same applies for const
:
All the considerations about the "temporal dead zone" apply to both let and const.
In other words, the reason this works:
var APP = APP || {};
is because of variable-hoisting which translates the above to:
var APP; // <-- declares APP
APP = APP || {}; // <-- initializes APP
and since variable-hoisting does not apply to either let
or const
:
const APP = APP || {}; // <-- Fails because APP is not yet initialized.
let APP = APP || {}; // <-- Fails for the same reason.
Finally, for the record (as rightly pointed out by naomik), the ||
operator is not a null-coalescing operator but rather a short-circuit OR operator.
The confusion over this is likely because of statements like this:
var n = n || '';
For the above statement, there are two things to bear in mind with these.
n
is not null
... it is undefined
(which is different from
null).
Because of variable-hoisting, that statement is the equivalent of:
var n; // n has the value of undefined
n = n || ''; // the comparison is now: undefined || '';
and since undefined
is a "falsy" value, the short-circuit OR operator returns the second value.
This behavior holds true for null
as well, because null
is also "falsy".