let, const, block scope, function scope and IIFEs
1. Overview
Variables declared with var in ES5 are function-scoped and Variables declared with let and const in ES6 are block-scoped.
2. Description
2.1 Function-scoped
Variables, which declared var, are only accessible inside of a function, but not from the outside. And we would use a variable before the declaration, it would be an "undefined" cause of hoisting.
function driversLicence5(passedTest) {
if (passedTest) {
// firstName is set to undefined, but work
console.log(firstName);
var firstName = 'John';
var yearOfBirth = 1990;
}
console.log(firstName + ', born in ' + yearOfBirth + ', is now officially allowed to drive a car.');
}
driversLicence5(true);
var i = 23;
// i isn't block-scoped variable, but same variable.
for (var i = 0; i < 5; i++) {
console.log(i);
}
// i is 5
console.log(i);
2.2 Block-scoped
Block is simply all the code that is wrapped between curly braces. So each time that we have an if statement or a for a block or a while block, we're actually creating a new block. Unlike variables declared by var, using variables declared by let or const doesn't work. This prevents something called the temporal-dead zone which basically just means that the variables are actually hoisted, but we still cannot access them before they are declared.
function driversLicence6(passedTest) {
// using before declaration doesn't work in let and const
//console.log(firstName);
let firstName;
const yearOfBirth = 1990;
if (passedTest) {
firstName = 'John';
}
console.log(firstName + ', born in ' + yearOfBirth + ', is now officially allowed to drive a car.');
}
driversLicence6(true);
let i = 23;
for (let i = 0; i < 5; i++) {
// i is block-scoped so it doesn't be changed by above var i
console.log(i);
}
// i is 23
console.log(i);
2.3 Data privacy
Block also gives us data privacy in a simple way instead of using IIEF.
// ES6
{
const a = 1;
let b = 2;
var c = 3;
}
// this is not accessible from outside of block
//console.log(a + b);
console.log(c);
// ES5
(function() {
var c = 3;
})();
//console.log(c);