ES6 introduced the following Features :
- var, let and const
- Template Literals or Strings
- Fat arrow functions
- Functions with default parameters
- object literals
- Sets and WeakSets
- Maps and WeakMaps
- Rest and Spread Operators (โฆ)
- Array & Object Destructuring
In this tutorial we will understand some of the features
var, let and const (ES6)
- var declarations are function scoped and supports hoisting
- let declarations are block scoped
- const declarations are block scoped
When to use Var, let and const ?
There is no as such rule stating where to use each of them, Everyone has different opinions. But according to the properties of these three, it should be used as follows.
- Use
var
for top-level variables that are shared across many (especially larger) scopes. - Use
let
for localized variables in smaller scopes. - Use
const
for, if there is no need to re-assign any variable likeconst PI = 3.14;
.
Let’s now deep dive to understand var, let and const better
var
Var are function scoped, which means they are still accessible outside the block scope even though we have declared them inside it.
// for loop is block scoped
for (var i = 0; i < 10; i++) {
var iAmInside = "I am available outside of the loop";
}
console.log(iAmInside);
// I am available outside of the loop
// block scope
if (true) {
var inside = "Inside";
}
console.log(inside);
// Inside
// Function scoped
function myFunc() {
var functionScoped = "I am available inside this function";
console.log(functionScoped);
}
myFunc();
// I am available inside this function
console.log(functionScoped);
// ReferenceError: functionScoped is not defined
This happens because of Hoisting.
Var are treated as if they are at the top of the function (or global scope) regardless of where the actual declaration occurs, this is called hoisting
var inside; // hoisted on the top of the function. As there is no function so it is present in the global scope.
// block scope
if (true) {
var inside = "Inside";
}
console.log(inside);
// Inside
// Function scoped. In this case value is hoisted inside the function
function getValue(condition) {
if (condition) {
var value = "blue";
return value;
} else {
// value exists here with a value of undefined
return value;
}
// value exists here with a value of undefined
}
console.log(getValue(true)); // blue
console.log(getValue(false)); // undefined
// while execution it is hoisted like this internally
function getValue (condition) {
var value; // value is hoisted as there is no value attached, so it is undefined
if (condition) {
var value = "blue";
return value;
} else {
// value exists here with a value of undefined
return value;
}
// value exists here with a value of undefined.
}
console.log(getValue(true)); // blue
console.log(getValue(false)); // undefined
Reassigning works in var ๐
var A = 10;
A = 15; // works
A = โHelloโ // works
console.log(โAโ, A)
Redeclaring works in var ๐
var A = 10;
var A = "Hello"; // works
let
Let are declared same as var but it limits the variable scope to the given block. That is why we should declare let at the top of the block so that is accessible throughout the block and its sub-blocks.
function getValue(condition) {
if (condition) {
let value = "blue"; // accessible inside the given scope only
return value;
} else {
// value does not exists here
return value;
}
// value does not exists here
}
console.log(getValue(true)); // blue
console.log(getValue(false)); // ReferenceError: value is not defined
let x = 10;
if (x == 10) {
let x = 11;
console.log(x); // 11 value of x inside if block
}
console.log(x); // 10 value of x global
Reassigning works in let ๐
let A = 10;
A = 15; // works
A = "Hello"; // works
Redeclarationโs does not work in let ๐
But Redeclaring works only in different scope
Suppose, Redeclared in Same Scope , let wonโt work ๐
let A = 10;
let A = 15; // error can-not be redeclared as A is already defined
Suppose, Redeclared in Different Scope , let will work ๐
let A = 10;
if (true){
let A = "test"; // works without error as scope is different
console.log('A', A) // test
}
console.log('A', A); // 10
const
Just Like let , const is also block scoped. But it differs from the fact that their variable cannot be redeclared or change by reassigning the value. The value remains Constant.
const abc = "XYZ";
let abc; // SyntaxError: Identifier 'abc' has already been declared
abc = "pqr"; // Typeerror: Assignment to constant variable
A variable declared using โconstโ cannot be redefined or re-declared within its scope. ๐
Every const declaration must be initialised at the time of declaration.
// Should be initialized while declaring
const XYZ; // SyntaxError: Missing Initializer in a const declaration
Const is block scoped.
if (true) {
const a = "I am inside";
console.log(a); // I am inside
}
console.log(a); // ReferenceError : a is not defined
However, the value a constant holds may be modified if it is an object:
const person = {
name: 'Sujay',
age: 25,
}
person.age = 26;
console.log(person.age); // 26
Const declarations for objects do not prevent modification of those objects. A const declaration prevents modification of the binding and not of the value of the binding.
But this will result in error.
const person = {
name: 'Sujay',
age: 25,
}
person = 26;
console.log(person); // TypeError: Assignment to constant variable.
Reassigning does not work with const ๐
const x = 10;
console.log(x); //prints 10
x = 11; // error: Assignment to constant variable.
const y;
y = 2; //error
Redeclaration also does not work with const ๐
const z = 12;
console.log(z) //prints 12
const z = 13; // error: Identifier โzโ has already been declared
// const in typescript
const userName = 'Max';
userName = 'MaxMillan'; // Typescript will throw error