ES6 part-2

Welcome back, if you came here after reading the part-1 of this article. If not, then it’s better you read the part-1 and come back here. In part-1, we covered some of the ES6 features such as Classes, Arrow functions, Destructing, Generator Functions, let, const and Template Strings. In part-2, we’ll be looking at the rest of the ES6 features that you should consider using in your projects if you haven’t yet.

Let us continue from where we left off …

ES6 features

Default parameter, Rest parameter and Spread operator

ES6 has introduced three new features for the better handling of functions. The first one is the default parameter. It is used to set a default value for the parameters during function calls when no value is specified. 

function testFunction (a, b=2, c=10) {
  console.log(a, b, c); // Outputs 5 2 10
}
testFunction(5);

When a value is specified, the specified value overwrites the default value.

The next one is the rest parameter. It can be used to pass in multiple parameters at once, especially in cases of function overloading.

function testFunction (a, b, …c) {
  console.log(a, b) // Outputs 10 20
  console.log(c); // Outputs Array(5)
} 
testFunction(10, 20, 30, 31, 31, 33, 34);

Here …c is the rest parameter and the syntax is … . It should always be at the end of the function parameters, otherwise, it won’t work. Also, it outputs an array containing the rest of the parameters.

The last one is the spread operator. It can be used on functions, as well as normal operations that require an array. The syntax is similar to the rest parameter.

function testFunction(a, b, c) {
  return a * b * c;  // Returns 350
} 
let arr1 = [10,7,5]; 
testFunction( …[arr1] );

When the number of parameters sent to the function does not match, then the remaining arguments are set to undefined.

Promises

The most predominant feature, which is now being used in many JS libraries, is the promises. They can be used for asynchronous operations and API calls to the server. They are methods that always return either a success or a failure. 

A promise can be in one of these states.

  • pending: initial state, neither fulfilled nor rejected
  • fulfilled: completed successfully
  • rejected: operation failed

Promises support two methods: then() and catch(). then() can be used to do further operations when a promise returns something or nothing at all. catch() can be used to handle promises when it throws some error. As both of these methods return promises again, they can be chained

A promise always returns resolve and reject methods. We can use resolve when what we were doing asynchronously was completed successfully and reject when it doesn’t.

function testFunction (a) {
   let test = new Promise((resolve, reject)=> {
       if(a == 10)
        resolve(“It’s right”);
       else
        reject(“It’s not right");
   })
   test.then(response=> {
       console.log(“its"+ response);
   }).catch(response=>{
       console.log(response);
   })
}
testFunction (10); // Outputs “Its right”
testFunction (20); // Outputs “It’s not right”

As you can see here, resolve() values can be accessed in then() and reject() values can be accessed in catch(). There is another handler called finally(), when used, gets called even when the promises are fulfilled or rejected.

Import and Export statements

If you are familiar with any programming languages like Java or Python, you must have come across import and export statements. These are now used in many javascript libraries.

Import, as the name suggests, imports bindings or methods from another file which has already exported its bindings. They are like Bacon and Eggs (BAE): they always go together. You must first export something in a file in order to import it in another.  

// ‘module-name’ refers to the file name which exports values or methods
import defaultExport from “module-name”; // ‘defaultExport’ takes the default export name of the module 
import * as exportName from “module-name”  // ‘*’ import all exports from the module
import {export1, export2 }  from “module-name” // Multiple imports 
import { export1 as exportName } from “module-name” // Specifying an alias name for the import
import ‘module-name’ // Executes the entire module code but doesn’t
export any.

Examples for import:

There are two types of export: named and default. There can be multiple named exports but only one default export specific to a module. Also, a named export must be imported only using the exported name but a default export can be imported using a different name.

Examples for export:

export default function() { … } 
export const variable;
export className; // Can export classes directly 
export someVariable from “module-name” // Exports a variable from another module.
export {variable1 as var1, variable2 as var2 }; 

Object literals - Enhanced

Objects, in javascript, can easily be created using the curly braces syntax, known as Object literals. We also know that objects can have properties and methods as properties. 

Prior to ES6, object properties are created using a key: value pair syntax. ES6 brings the following changes:

  1. Shorthand syntax for declaring properties  and methods
  2. Computed property names

Shorthand syntax for properties and methods:

//ES5
function testBike(engine, model) {
  return {
  	engine: engine,
	model: function() {
		return model;
	},
  } 
} 
//ES6
function testBike(engine, model) {
  return {
  	engine, 	// Possible only when key and value names are the same
	model() {	// Shorthand method declaration
		return model;
	}
  } 
} 

Computed property names:

Computed properties are properties whose property-name gets computed or generated dynamically. Since object properties can be accessed using the dot notation or the square bracket notation, computed properties can be used to specify properties inside square brackets.

let species = “animal”;
let i = 0;  
let being = {
	[ species + i ]: “Elephant”,
	[ species + (i+1) ]: “Giraffe”
} ;
console.log(being.animal1) // Outputs Elephant
console.log(being.animal2) // Outputs Giraffe

This might seem like an under-used feature but this dynamism is useful when building complex applications. 

String, Number, Array helpers, and Object.assign:

Libraries reduce our efforts and also helps in achieving our results faster. These are some of the new additions in ES6.

//Number helpers
Number.isNaN(“Test”) // false
Number.isInteger(10) // true
//String helpers
“string”.includes(“s”) // true
“test”.repeat(2) // testtest
//Array helpers
// Creates an array from an array-like or iterable objects
Array.from(“test”) // Outputs [ ’t’, ‘e’, ’s’, ’t’ ]
//Fills an array with a static value (Overwrites original array)
[ 10, 12, 14, 16, 18 ].fill(100, 2); // Outputs [10, 12, 100, 100, 100]
//Finds the first condition matching element and index in an array respectively
[10, 31, 4, 50, 100 ].find(value=> value > 30) // Outputs 31
[10, 31, 4, 50, 100 ].find(value=> value > 30) // Outputs 1
//Object.assign copies all enumerable properties from the source to the target object. Duplicate objects are overridden.
let source =  {a: 12, c: 30 };
let target =  {a:10, b: 20};
Object.assign( target, source ); // Returns target object  { a: 12, b: 20, c: 30 }
Conclusion

That brings us to the end of the article. I hope you will start using these new features in your upcoming projects.

What we have seen so far are only some of the many features that were introduced in ES6. I highly recommend visiting this page, which gives a full overview of all the features and how they differentiate from the earlier version.

Feel free to give your suggestions if you think I missed something or if you think this article can be improved.

Signing off for now.

Arigato Gozaimasu 🙂

+1

46