- Introduced in ES6
- Two new ways to declare a variable
Two different types of scope:
- Function scope
- Global scope
function getName() {
var myName = 'robyn';
return myName;
}
getName();
console.log(myName); // Uncaught ReferenceError: myName is not defined
myName
is scoped to the getName
function, therefore it's only accessible inside the getName
function (or any functions nested within it).
function getName() {
var myName = 'robyn';
function logName(){
console.log(myName); // myName is accessible here.
}
logName();
}
getName();
console.log(myName); // Uncaught ReferenceError: myName is not defined
What about block scope
?
function sayHelloToYourInstructors(instructors){
var greetings = [];
for (var index = 0; index < instructors.length; index++) {
var instructor = instructors[index];
greetings.push(`Hello ${instructor}!`);
}
console.log(index); // Logs: 3
console.log(instructor); // Logs: 'Elise'
console.log(greetings); // Logs: ['Hello Rami','Hello Robyn','Hello Elise']
return greetings;
}
sayHelloToYourInstructors(['Rami','Robyn','Elise']);
console.log(index); // Uncaught ReferenceError: index is not defined
console.log(instructor); // Uncaught ReferenceError: instructor is not defined
console.log(greetings); // Uncaught ReferenceError: greetings is not defined
Recall that any variable declared using var
are initialized with the value of undefined
during the creation phase of an execution context. This is what we refer to as hoisting.
function sayHelloToYourInstructors(instructors){
console.log(index); // Logs: undefined
console.log(instructor); // Logs: undefined
console.log(greetings); // Logs: undefined
var greetings = [];
for (var index = 0; index < instructors.length; index++) {
var instructor = instructors[index];
greetings.push(`Hello ${instructor}!`);
}
console.log(index); // Logs: 3
console.log(instructor); // Logs: 'Elise'
console.log(greetings); // Logs: ['Hello Rami','Hello Robyn','Hello Elise']
return greetings;
}
Variables declared with var
are function scoped, whereas those declared with let
are block scoped.
{ // <---- The start of the block
// Everything between the {} is block scoped
} // <---- The end of the block
function sayHelloToYourInstructors(instructors){
var greetings = [];
for (var index = 0; index < instructors.length; index++) {
var instructor = instructors[index];
greetings.push(`Hello ${instructor}!`);
}
console.log(index); // Logs: 3
console.log(instructor); // Logs: 'Elise'
console.log(greetings); // Logs: ['Hello Rami','Hello Robyn','Hello Elise']
return greetings;
}
Variables declared with let
are block scoped, not function scoped. This means that they will not be accessible outside of the block they are declared in.
function sayHelloToYourInstructors(instructors){
let greetings = [];
for (let index = 0; index < instructors.length; index++){
let instructor = instructors[index];
greetings.push(`Hello ${instructor}!`);
}
console.log(index); // Logs: Uncaught ReferenceError: index is not defined
console.log(instructor); // Logs: Uncaught ReferenceError: instructor is not defined
console.log(greetings); // Logs: ['Hello Rami','Hello Robyn','Hello Elise']
return greetings;
}
Variables declared with let
are not hoisted. This means you'll get a Reference
error if you try to access a variable declared with let
before it's declaration.
function sayHelloToYourInstructors(instructors){
console.log(index); // Logs: undefined
console.log(instructor); // Logs: undefined
console.log(greetings); // Logs: undefined
var greetings = [];
for (var index = 0; index < instructors.length; index++) {
var instructor = instructors[index];
greetings.push(`Hello ${instructor}!`);
}
console.log(index); // Logs: 3
console.log(instructor); // Logs: 'Elise'
console.log(greetings); // Logs: ['Hello Rami','Hello Robyn','Hello Elise']
return greetings;
}
function sayHelloToYourInstructors(instructors){
console.log(index); // Logs: Uncaught ReferenceError: index is not defined
console.log(instructor); // Logs: Uncaught ReferenceError: instructor is not defined
console.log(greetings); // Logs: Uncaught ReferenceError: greetings is not defined
let greetings = [];
for (let index = 0; index < instructors.length; index++) {
let instructor = instructors[index];
greetings.push(`Hello ${instructor}!`);
}
console.log(index); // Logs: Uncaught ReferenceError: index is not defined
console.log(instructor); // Logs: Uncaught ReferenceError: instructor is not defined
console.log(greetings); // Logs: ['Hello Rami','Hello Robyn','Hello Elise']
return greetings;
}
Variables declared with const
are block scoped, like those declared with let
.
Variables declared with const
, like those declared with let
are not hoisted.
Variables declared with const
cannot have their value reassigned
const robynsAge = 16;
// Does Robyn age?
robynsAge = robynsAge +1;
// Uncaught TypeError: Assignment to constant variable.
// No she does not! :D - What a timeless, ageless youth! Waw.
(For those of you that don't know what a Trapper Keeper is)
const robynsTrapperKeeper = {
color: 'Hot Pink',
owner: 'Robyn Heslop',
level: 'Over 9000'
};
// Can I nick it?
robynsTrapperKeeper.owner = 'Rami Ruhayel'; // Yes I can!
// What if I try to swap it out for another, less excellent Trapper Keeper?
robynsTrapperKeeper = {
color: 'Beige',
owner: 'Dick Dirgler',
level: 'Low AF'
} // Uncaught TypeError: Assignment to constant variable.
var
should be a-var-ded. (Hyuk, Hyuk, Hyuk! Thanks Robyn...)
Use const
unless you have a good reason not to! An example of a situation where const
is not appropriate is when declaring a counter to be used in for
loop:
for (const i = 0; i < 3; i++){
}
// Uncaught TypeError: Assignment to constant variable.
Instead, you should use let
:
for (let i = 0; i < 3; i++){
}
Basically, for variable that don't need their value to change, use const
, otherwise use let
. Don't ever use var
again! ;)
type | scope | hoisted |
---|---|---|
var |
function | ✅ |
let |
block | ❌ |
const |
block | ❌ |