Get Started with Modern React: Intro, Setup, and ES6 Basics
S01・V07: Variables
- We will look at variables declared with“var”.
- We will look at variables declared with “let” in ES6.
- We will look at constant variables declared with “const” in ES6.
var
From the 1st Edition of JavaScript until the 6th Edition, the only way to declare a variable was with the keyword var
.
For example, the variable with the name x
is declared as follows:
var x;
If it is not initialized to a value, it is undefined
.
var x;
console.log("x:", x); // Prints `x: undefined`
The console logs: x: undefined
.
Initializing var
You can optionally initialize the variable to a value when it is declared. For example:
var y = 5;
console.log("y:", y); // Prints `y: 5`
The console prints y
to its initialized value of 5
.
Execution Context
The scope of a variable declared with var
is its current “execution context”.
The execution context is either the enclosing function, or if it is declared outside any function, it is global.
We can demonstrate this by setting up a function, with a variable, i
, declared in the initialization expression of a for
loop.
function test() {
for (var i = 0; i < 3; i++) {
console.log("i inside loop:", i); // Prints `i inside loop: 0`, `i inside loop: 1`, `i inside loop: 2`
}
}
test();
The console prints the values 0
, 1
, and 2
, inside the loop.
Hoisting var
We will also print the value of the variable i
, before, and after, the loop.
function test() {
console.log("i before loop:", i); // Prints `i before loop: undefined`
for (var i = 0; i < 3; i++) {
console.log("i inside loop:", i); // Prints `i inside loop: 0`, `i inside loop: 1`, `i inside loop: 2`
}
console.log("i after loop:", i); // Prints `i after loop: 3`
}
test();
Even though the variable is declared in the loop, it is evaluated before the loop, and shows the value undefined
, rather than throwing an error. Any variable declared with var
is processed before any code is executed, which is equivalent to declaring it at the top of its execution context. This behavior is called “hoisting”. Since we have declared i
within the test
function, its execution context is the function, and the variable declaration of i
is hoisted to the top of the function.
This is equivalent to writing the following:
function test() { var i;
console.log("i before loop:", i);
for (i = 0; i < 3; i++) { console.log("i inside loop:", i);
}
console.log("i after loop:", i);
}
test();
The output is the same as before. For clarity, it is recommended to always declare var
variables at the top of their scope.
Reassigning var
Variables declared with var
can be reassigned.
var x = 1;
console.log("x:", x); // Prints `x: 1`
x = 2;
console.log("x:", x); // Prints `x: 2`
The variable x
is assigned the value 1
, and it is then reassigned the value 2
.
Redeclaring var
Variables declared with var
can be redeclared.
var x = 1;
console.log("x:", x); // Prints `x: 1`
var x = 2;console.log("x:", x); // Prints `x: 2`, same variable!
The variable x
has the value 1
, and it is then redeclared to have the value 2
. Note that we are dealing with the same variable x
when it is redeclared. It does not become a new variable.
function test() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log("x:", x); // Prints `x: 2`
}
console.log("x:", x); // Prints `x: 2`
}
test();
The variable x
was assigned the value 1
on line 2, and then reassigned to the value 2
on line 4, so it prints out with the reassigned value on line 5, and again on line 7.
let
Since JavaScript’s 6th Edition, which is also called “ES6” for short, we can also declare variables with the keyword let
.
For example, the variable with the name x
would be declared as follows:
let x;
If not initialized to a value, it is undefined
.
let x;
console.log("x:", x); // Prints `x: undefined`
The console logs: x
is undefined
.
Initializing let
You can optionally initialize the variable to a value when declaring it.
For example:
let x = 7;
console.log("x:", x); // Prints `x: 7`
The console prints y
to its initialized value of 7
.
The scope of a variable declared with let
is its enclosing block, or the expression in which it is used. Let’s use the same loop example as we did previously:
function test() {
console.log("i before loop:", i);
for (let i = 0; i < 3; i++) {
console.log("i inside loop:", i);
}
console.log("i after loop:", i);
}
test();
We get an uncaught ReferenceError
stating that i is not defined
, for the log output before the loop. In other words, variables declared with let
are not hoisted.
Remove the console.log()
before the loop.
function test() {
for (let i = 0; i < 3; i++) {
console.log("i inside loop:", i);
}
console.log("i after loop:", i);
}
test();
We also get an uncaught ReferenceError
stating that i is not defined
, for the console.log("i after loop:", i)
. Since the variable i
is declared with the keyword let
, it is only defined within the for
loop.
Reassigning let
Variables declared with let
can be reassigned.
let x = 7;
console.log("x:", x); // Prints `x: 7`
x = 8;
console.log("x:", x); // Prints `x: 8`
The variable x
is assigned the value 7
, and it is then reassigned the value 8
.
Variables declared with let
cannot be redeclared within the same scope.
let x = 7;
console.log("x:", x);
x = 8;
console.log("x:", x);
We get an uncaught SyntaxError
stating that the identifier 'x' has already been declared
.
Since let
variables are scoped to the block they are in, if they have different scopes, then they are different variables, even if they have the same name.
function test() {
let x = 7;
if (true) {
let x = 8; // different variable
console.log("x:", x); // Prints `x: 8`
}
console.log("x:", x); // Prints `x: 7`
}
test();
The variable x
is assigned the value 8
within the scope of the if
block, and a different variable with the same name x
is assigned the value 7
within the scope of the function
.
const
Since JavaScript “ES6”, we also have the const
variable declaration. These variables are called “constants”.
A “constant” cannot change through reassignment:
const x = 3;
console.log("x:", x); // Prints `x: 3`
x = 4;
console.log("x:", x); // Prints `Uncaught TypeError: Assignment to a constant variable.`
We get an uncaught TypeError
when we try reassignment to a constant variable.
Constants are block-scoped, much like variables defined using the let
statement.
if (true) {
const x = 4;
console.log("x:", x); // Prints `x: 4`
}
console.log("x:", x); // Prints `Uncaught ReferenceError: x is not defined.`
For the console.log()
, outside the if
statement, we get an uncaught ReferenceError
, stating that x
is not defined, because its scope is only within the if
block.
A constant cannot be redeclared, within the same scope.
if (true) {
const x = 4;
console.log("x:", x);
}
console.log("x:", x);
We get an uncaught SyntaxError
stating that the identifier 'x' has already been declared
.
However, if the same variable name is declared within different scopes, this is not a redeclaration, since we are dealing with two separate variables:
function test() {
const x = 7;
if (true) {
const x = 8; // different variable
console.log("x:", x); // Prints `x: 8`
}
console.log("x:", x); // Prints `x: 7`
}
test();
The constant x
is assigned the value 8
within the scope of the if
block, and a different constant with the same name x
is assigned the value 7
, within the scope of the function
.
Block-scoping makes it easier to reason about code, so we will only use let
and const
variables during this video course.
Summary
We will now summarize the differences between var
, let
, and const
:
var
has scope of its execution context, meaning its function scope or global scope. Ignoring the global scope, we say it has “function scope”.let
andconst
, on the other hand, are scoped to the block they are in (“block-scoped”).- The declaration of a
var
variable is hoisted to the top of its function. - On the other hand,
let
andconst
variables are not hoisted. - Both
var
andlet
variables can be reassigned. - However,
const
is a constant, so it cannot be reassigned. var
can be redeclared.- But, both
let
andconst
cannot be redeclared in the same scope.
Next Up…
In the next video, we will talk about ES6 template literals.