nism called hoisting. JavaScript scans the entire scope (either a function or the global
scope), and any variables declared with
var
are hoisted to the top. What’s important to
understand is that only the declaration—not the assignment—is hoisted. So JavaScript
would interpret the previous example as:
var
x
;
// declaration (but not assignment) hoisted
x
;
// undefined
x
=
3
;
x
;
// 3
Let’s look at a more complicated example, side by side with the way JavaScript inter‐
prets it:
// what you write // how JavaScript interprets it
var
x
;
var
y
;
if
(
x
!==
3
) {
if
(
x
!==
3
) {
console
.
log
(
y
);
console
.
log
(
y
);
var
y
=
5
;
y
=
5
;
if
(
y
===
5
) {
if
(
y
===
5
) {
var
x
=
3
;
x
=
3
;
} }
console
.
log
(
y
);
console
.
log
(
y
);
} }
if
(
x
===
3
) {
if
(
x
===
3
) {
console
.
log
(
y
);
console
.
log
(
y
);
} }
I’m not suggesting that this is well-written JavaScript—it’s needlessly confusing and
error-prone to use variables before you declare them (and there’s no practical reason
to do so). But this example does make clear how hoisting works.
Another aspect of variables declared with
var
is that JavaScript doesn’t care if you
repeat the definition:
// what you write // how JavaScript interprets it
var
x
;
var
x
=
3
;
x
=
3
;
if
(
x
===
3
) {
if
(
x
===
3
) {
var
x
=
2
;
x
=
2
;
console
.
log
(
x
);
console
.
log
(
x
)
:
} }
console
.
log
(
x
);
console
.
log
(
x
);
This example should make it clear that (within the same function or global scope),
var
can’t be used to create new variables, and variable masking doesn’t happen as it
does with
let
. In this example, there’s only one variable
x
, even though there’s a sec‐
ond
var
definition inside a block.
Again, this is not something I’m suggesting that you do: it only serves to confuse. The
casual reader (especially one familiar with other languages) may glance at this exam‐
126 | Chapter 7: Scope