ES6 deep dive

By | November 5, 2017

ES6 Introduction

JavaScript is an implementation of ECMA script. The link to the full specification can be found at https://www.ecma-international.org/ecma-262/6.0. I will try to highlight some features that will help developers write cleaner JavaScript code. As we all know JavaScript has been there for years, I remember working on JavaScript in the year 2000, back then having bare minimum tools working with it was a difficult experience.

Today we have many runtimes, browsers, and tools that help us in making awesome UI experience with JavaScript, HTML, and CSS. ES6 introduces an extensive amount of new syntax to the language but it is all for good believe me. Let’s start the journey.

ES6 Features

Variables and Parameters

let

let is a new keyword introduced with ES6. It allows you to declare a variable like var but it will provide block scoping, unlike var. A variable declared with var in a block can be updated even outside its declaration block. This can be a coding error and can result in some debug hours. let gives you block safety.

	var doSomething = function(flag) {
		if(flag) {
			let x = 8;
			return x;
		}
	};
	var result = doSomething(true);
	//result variable will be 8;

In the above code, we can't use x variable outside the if block as it doesn't exist there. The scope of x is within the if block. If we declare it using a var then that variable will be accessible outside the if block and can be returned with a false flag.

const

There is a new const keyword that can be used to set constants in JavaScript code.

	const CURRENT_YEAR = 2017;
	CURRENT_YEAR = 2018;
	//You will get error on assignment "TypeError: Assignment to constant variable."

const keyword is provided to do what the name suggests, keep things constant. So in the above code changing the constant value from 2017 to 2018 will not work.

Destructuring

Destructuring is an easy way to swap values between variables. It can be achieved as shown in below-given example.

	let a = 10;
	let b = 20;
	let c = 30;
	[a, b, c] = [b, c, a];

The above code will return a = 20, b = 30 and c = 10;

Default Parameter Values

Anyone who has worked with Visual Basic has always requested for the feature to have a default value of function parameters. ES6 now helps us with that.

	var doSomething = function(flag = false) {
		if(flag) {
			return "was true";
		} else {
			return "was false";
		}
	};
	doSomething(); //returns "was false"
	doSomething(true); //returns "was true"

Template Literals

This helps in replacing concatenations with a template literal. You can use it as placeholders with dynamic values where needed.

	let name = "Bhawesh";
	let city = "Chicago";
	let zip = 1245;
	let info = `The author name is ${name}, he lives in ${city}, its zip is ${zip}`;

Keep an eye for the backticks used in the replacement string.

Spread Operator

The spread operator is used for array construction, destructuring, and to fill function arguments from an array.

	var doSomething = function(a, b, c) {
		return a + b + c;
	};
	var output = doSomething(...[10, 20, 30]);
	//output will have 60;
	var a = [4, 5, 6, 7, 8];
	var b = [1, 2, 3, ...a, 9, 0];
	//output if printing b will be [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

Rest Parameters

It's basically destructuring. The last parameter of a function can be a rest parameter. A rest parameter is something defined with three dots in front of the parameter name. An example is given below.

	var doSomething = function(...parameters) {
		let result = 0;
		for (let i=0; i< parameters.length; i++) {
			result += parameters[i];
		}
		return result;
	};
	var output = doSomething(10, 20, 30);
	//output will have 60;

Class

Class, as we all know and have used in several object oriented languages, is a blueprint. We create instances of the class commonly referred to as an object. ES6 provides us with a class syntax.

	class Car {
	  constructor(door, color) {
	    this.door = door;
	    this.color = color;
	  }
	  // Getter
	  get mileage() {
	    return "21 mph";
	  }
	  // Method
	  describeCar() {
	    return `The car has ${this.door} doors and is of ${this.color} color.`;
	  }
	}
	const car = new Car(2, 'Red');
	console.log(car.mileage);
	console.log(car.describeCar());

Constructor

The constructor is defined by keyword constructor with all the required parameters. Note that there can be only one constructor per class and you can't have overloaded constructors.

	class Car {
	  //constructor
	  constructor(door, color) {
	    this.door = door;
	    this.color = color;
	  }
	}

Getter and Setter

Getter and Setters are defined to set and get properties of a class. In the code below we have paint attribute of a car and it has getter and setter defined as get paint() and set paint(value).

	class Car {
	  constructor(door) {
	    this.door = door;
	  }
	  // Getter
	  get paint() {
	    return this.paintType;
	  }
	  set paint(value) {
	   this.paintType = value;
	  }
	  // Method
	  describeCar() {
	    return `The car has ${this.door} doors and has a ${this.paint} paint.`;
	  }
	}
	const car = new Car(2);
	car.paint = 'Glossy';
	console.log(car.describeCar());
	//prints- The car has 2 doors and has a Glossy paint.

Inheritance, Super or base class

Using ES6 syntax now you can have class extended from another class. In the below example we have a Person class and an Employee class. Employee class extends Person and adds an attribute called designation. Note constructor of Employee class calls super(name). This allows it to pass required attributes for the constructor of the base class (Person in this case).

	class Person {
		constructor(name) {
	  	this._name = name;
	  }
	}
	class Employee extends Person {
		constructor(name, designation) {
	  	super(name);
	    this._designation = designation;
	  }
	}
	var person = new Person("Bhawesh");
	console.log(person);
	var employee = new Employee("Aadrika", "CEO");
	console.log(employee);

Arrow

You can use Arrow (also called as Lambda functions in a few languages) in ES6. Some examples below give a small demonstration of how compact your code can be by using these arrow functions.

	let add = (x, y, z) => {
		return x + y + z;
	};
	console.log(add(1, 2, 3)); //returns 6
	let square = x => x * x;
	console.log(square(4)); //returns 16
	var numbers = [2,4,6,8];
	var sum = 0;
	numbers.forEach(item => sum += item);
	console.log(sum); //returns 20
	var squareArray = numbers.map(n => n * n);
	console.log(squareArray); //returns [4, 16, 36, 64]

Built-in objects

I will try to cover some built-in objects that will be handy for daily use.

Array

Wanted to show some things that can be done on an array.

	var testArray = [10, 15, 20];
	var match = testArray.find(item => item > 10);
	console.log(match); //returns first match 15 in this case
	var match = [10, 15, 20].findIndex(item => item > 15);
	console.log(match); //returns array index 2 which is third position 20 number value
	var testArray1 = [1,2,3,4,5];
	testArray1.fill('Bhawesh');
	console.log(testArray1); //returns all elements as Bhawesh
	var testArray2 = [1,2,3,4,5];
	testArray2.fill('bhawesh', 2, 3);
	console.log(testArray2); //returns [1, 2, "bhawesh", 4, 5]

Map

Map data type contains key-value pair where you can use a key to get its respective value.

	let testMap = new Map([['name','Bhawesh'],['age',30],['weight','170']]);
	console.log(testMap); // prints map with three indexes, each one containing a key and value;
	console.log(testMap.get("name")); //returns Bhawesh
	let items = testMap.entries(); //returns an iterator and you can loop through
	console.log(items);
	console.log(items.next().value);

Object.assign()

Object assign is something I am very excited to use. It helps you to make a copy of your object. Please note that it makes a copy of the property value and if it is reference type then it is not a deep copy. To do deep copy you can still use JSON stringify.

Syntax: Object.assign(target, ...sources). It takes three parameters. The first one is the new instance of the object called target. the second parameter is a rest parameter that allows you to pass one or n number of objects. We use to make a copy of state object using object assign while working with Redux for state management.

	let obj1 = { a: 2 };
	let obj2 = { b: 4 };
	let obj3 = { c: 6 };
	let newObject = Object.assign(obj1, obj2, obj3);
	console.log(newObject); // returns { a: 2, b: 4, c: 6 }
	console.log(obj1);  // { a: 2, b: 4, c: 6 }, target object itself is changed.
	let obj4 = { a: 2 , b: 1, c: 4};
	let obj5 = { a: 6, b: 4, c: 2 };
	let obj6 = { c: 6, a: 10};
	let newObject1 = Object.assign(obj4, obj5, obj6);
	console.log(newObject1); // returns { a: 10, b: 4, c: 6 }
	console.log(obj4);  // { a: 10, b: 4, c: 6 }, right most object overrides values in target.

Hopefully, you all like this ES6 deep dive post. I will add more things to this post later. I was not able to write any post for around a year due to the hectic schedule. Things are looking better now giving me more time to write things often.

Thank you