ES6-let and const

Variable- Formally known as binding as a name is bound to a value inside a scope.

Block Level Scoping- Variables that are inaccessible outside a given block scope. Also known as lexical scope. Created inside these following places:

  • Inside a function
  • Inside a block({})

Introducing let declarations- The syntax is same as the var. let declarations are not hoisted onto the top of enclosing block. It’s best to place them first in the block so they are accessible to the entire block.

Cannot Redeclare the variable like we do in var

1
2
3
4
5
6
7
8
9
var count = 40;
var count = 20;
//No Error even in strict mode
let count = 20;
//Error-Identifier 'count' has already been declared with var. Error-If in the same scope or block;
let foo = 20;
let foo = 30;
// Error- Identifier 'foo' has already been declared

const declaration - Variables declaring const are considered constants meaning their values cannot be changed once set. const is block level variable and it’s declarations is not hoisted as well.

1
2
3
4
5
6
// Valid Declaration
const count = 20;
count = 10;
// Error- Assignment to constant variable.Cannot be assigned to a new value later.
const foo;
// Error-Missing Initialization

The value a const hold can be modified if it’s an Object. const prevents modification of the variable not modification of the bound value.

1
2
3
4
5
6
7
8
9
10
const obj = {
name:"John"
}
obj.name = "Jane";
// No error
// Throws an Error.
obj = {
name:"Jane"
}

Temporal dead zone(TDZ) - let and const bindings are not hoisted so they can’t accessible before their declaration. Any attempt to access the variable results in runtime error.

1
2
3
4
if(true){
console.log(typeof count); // Throws an Error
let count = 10;
}

Block binding in loops- Only the loop will have access to the count variable and is meant to use only inside the loop.

1
2
3
4
5
6
7
8
9
10
11
12
var a = {};
for(var i = 0 ; i < 5 ; i++) {
a[i] = function(){console.log(i);}
}
a[0](); // 5
a[1](); // 5 // The reason is i is shared across each iteration of the loop meaning all the functions hold a reference to the same variable.To fix this developers used IIFEs to force a new copy of the variable each time
for(let i = 0 ; i < 5 ; i++) {
a[i] = function(){console.log(i);}
}
a[0](); // 0 Block Scope Binding simplifies this problem for us. This loop works the same as the IIFE but a lot cleaner code.let creates a new variable each time
a[1](); // 1

const behaves differently in loops. If we use const in a for loop it will throw an error after the first iteration but it can be used with for-in loop(because the loop creates a new binding on each itertion ) and works the same way as let.

Global block binding - When var is used in the global scope it creates a new global variable which is a property on the global object(window in browser) that means we can accidentally overwrite an existing global using var.

1
2
3
4
console.log(window.RegExp); // function RegExp() { [native code] }
var RegExp = 20;
console.log(RegExp); // 20 Original RegExp is overwritten by our var declaration.
console.log(window.RegExp); // 20

if we use let or const instead in the global scope a new binding is created in the global scope but no property is added to the global object. This means we cannot overwrite a global variables. This makes let and const much safer to use in the global scope.

Best practice - use const by default and only use let when you know a variable value need to change. The rationale is the most variables should not change their value after initialization because unexpected value changes are a source of bugs.

Proudly powered by Hexo and Theme by Hacker
© 2017 Mohit Garg