If you’ve worked with JavaScript at all you’ve undoubtedly used the var
keyword to define variables, but there’s now other ways to define variables too: let
and const
.
First let’s do a quick review of var
. Two of the key properties of variables
defined with var
are that:
1) They are scoped to the function in which they are declared, or if there is no function, the global/window frame.
2) They are hoisted at compile time, meaning that they are allocated in memory as soon as the script loads.
Here’s an example:
console.log("before the block myVar equals " + myVar);
if (1 < 2){
var myVar = "inside an if block";
console.log("inside the block myVar equals " + myVar);
}
console.log("after the if block myVar equals " + myVar);
Output:
"before the block myVar equals undefined"
"inside the block myVar equals inside an if block"
"after the if block myVar equals inside an if block"
Variables defined with let
You can also define variables using the keyword let
instead of var
.
Here’s how let
variables differ from var
:
1) Thy are scoped to the block in which they are declared. In addition to functions, this includes things like if statements and while/for loops.
2) They are not hoisted meaning that they do not exist in memory in any way until the interpreter gets to the line on which they are defined.
Let’s look at what happens if you swap out var myVar
with let myLet
in the code from above:
console.log("before the block myLet equals " + myLet);
if (1 < 2){
let myLet = "inside an if block";
console.log("inside the block myLet equals " + myLet);
}
console.log("after the if block myLet equals " + myLet);
Output:
ReferenceError: myLet is not defined
Because let variables are not hoisted, the code chunk error-ed on the first line and will not continue.
Let’s skip that first line though and see what we get:
if (1 < 2){
let myLet = "inside an if block";
console.log("inside the block myLet equals " + myLet);
}
console.log("after the if block myLet equals " + myLet);
Output:
"inside the block myLet equals inside an if block"
ReferenceError: myLet is not defined
Another error, but this time it’s after the if block has ended. As you
can see, the myLet
only existed in the if block. Unlike a var
variable, it
doesn’t exist in any form outside of this block.
In the right circumstances, let
has several advantages over var
, such as
performance. Because let
variables are cleaned up after their block
completes, they’re no longer sitting around taking up memory. They’re also great
for temporary variables such as in loops, and allow for cleaner code.
Consider the following:
var array = [1,2,3];
for (var i = 0; i < array.length; i += 1) {
console.log(array[i]);
}
console.log("i is still equal to " + i);
Output:
"1"
"2"
"3"
"i is still equal to 3"
We don’t think about it, but i
is still there in memory after the loop
completes, taking up space, and possibly colluding with other loops. If we
define i
with let
instead, it will be cleaned up as soon as the loop is
over:
var array = [1,2,3];
for (let i = 0; i < array.length; i += 1) {
console.log(array[i]);
}
console.log("i is now " + i);
Output:
"1"
"2"
"3"
ReferenceError: i is not defined
Variables defined with const
Variables defined with const
are very similar to let
variables.
1) Just like let
, they are scoped to the block in which they are declared.
In addition to functions, this includes things like if statements and while/for
loops.
2) Just like let
, they are not hoisted meaning that they do not exist in
memory in any way until the interpreter gets to the line on which they are
defined.
3) Variables defined with const
will throw an error if you attempt to re-
define them.
Here’s const
in action:
const name = "Ralph";
console.log("In the global frame the name is " + name);
if (1 < 2){
const name = "Sam";
console.log("In this block name is " + name);
}
console.log("Back in the global frame the name is " + name);
const name = "Another name";
Output:
SyntaxError: Identifier 'name' has already been declared
As you can see, because we attempted to redefined name
in the global namespace, it gave us an error.
There is one cavavet to the idea that const
variables can’t be redefined to be aware of: When the variable is an array or object, the internal elements can still be updated. So the following is still possible:
const a = { text: 'Hello' };
a.text = 'Goodbye';
Summary
Type | Scope | Hoisting | Other |
---|---|---|---|
var | function | hoisted | N/A |
let | block | not hoisted | N/A |
const | block | not hoisted | error if re-defined |
So there you have it. As always the MDN pages on both let and const are great place to go for more information.