Why Does A `let` Assignment That Uses The Same Variable Name In Its Right-hand Side Throw A ReferenceError?
Solution 1:
Variables declared with
var
are hoisted to the top of the enclosing function or global scope. They are assigned the initial value ofundefined
. Hence the example line of codevar x = x || {};
is transformed by hoisting and default value initialization into this equivalent code:var x = undefined; x = x || {};
Because
x
already has a value when the right-hand side of the assignment statement is evaluated, the code proceeds normally.Side note: You can declare a variable with
var
even after the first assignment (due to top-hoisting), and declaring more than once is idempotent (e.g.var x; var x;
).Variables declared with
let
andconst
are hoisted to the top of the enclosing block, but are not given a default value. If such a variable is read before a value is assigned, aReferenceError
is thrown. Your example line of code is transformed by hoisting into this equivalent code:let y; y = y || {};
To execute the assignment statement, the right side is first evaluated, then its value is assigned to the variable on the left side. But in this case, the right side reads
y
, which has not been assigned a value yet — hence an error is thrown.Everything that is in the same scope as the
let
statement, but executed earlier (i.e. abovelet
or the right-hand side of alet
assignment) is within the Temporal Dead Zone (TDZ).
Note that in JavaScript, a piece of code like let x = x + 1;
throws an exception only if execution reaches that statement. Whereas in other languages like Java, the same piece of code is always a compile-time error, even if it’s buried inside an if(false){...}
. This emphasizes the behavior of variable hosting, and the fact that JavaScript examines what the code means when it is executed, hence these examples are not syntax errors in a strict sense.
Post a Comment for "Why Does A `let` Assignment That Uses The Same Variable Name In Its Right-hand Side Throw A ReferenceError?"