ES6 part-1

Javascript has come a long way ever since it was created in 1995 by Brendan Eich. It was inspired by languages like Java, Schema and Self. Now it has reached a more versatile state through ES6. To know more about Javascript and its history, I recommend you read this article.

But unlike Java, Javascript is a scripting language. A scripting language is (technically speaking) a programming language but it is rather interpreted than compiled

Javascript is the duct tape of the internet.

Charlie Campbell

In this post, I’ll be explaining some of the ES6 (ECMASCRIPT 2015) features, that are currently being used by developers and why you should use them too. If you are not comfortable with previous versions of JS yet, then I recommend you to get familiar with them before diving into this article. 

Without further ado, let’s jump into it.

ES6 browser compatibility

Since JS (short form for JavaScript) has become an integral part of any browser that we use today, it is mandatory that any new version released should be able to support various browsers. This is the list of browsers that supported ES5 (an earlier version of JS) and will be supporting ES6 going forward.

So before you start developing something, make sure to look at this list. If you still would like to write your code using ES6 features for browsers that don’t support them, you can use a transpiler like Babel, which converts ES6+ features into a backward compatible code which can be supported by older versions of the browsers.

ES6 features

Classes

If it rings a bell, then you must be familiar with some server-side languages like PHP, Java, Python, etc. If not, then forget I said that.

In Object-Oriented Programming, otherwise referred to as OOP, a class can be defined as a blueprint, that contains attributes and methods needed to create an object. This makes it easy to create any number of objects using the same class. 

A class name should always begin with a capital letter as per the conventions. An example of a class is :

class TestClass {
  constructor(name,age){
    this.name = name;
    this.age = age;
  }
 addAddress(address){
	this.address = address;
 }
}
const testObject = new TestClass(“TestUser”,25);
testObject.addAddress(“Test Address”);

It has a default constructor function that can be used to initialize an object during the time of its creation. Here, name and age are known as properties and addAddress is a method or a function. 

Classes can also have static methods that can only be accessed by the class itself and not the object instances. Also, static methods do not have access to class properties and methods.

class TestClass {
  constructor(name,age){
    this.name = name;
    this.age = age;
  }
  addAddress(address){
    this.address = address;
  }
  static  test(){
    console.log(“This is a static method”);
  }
}
const testObject = new TestClass(“TestUser”,25);
testObject.addAddress(“Test Address”);
testObject.test(); // Throws Error: Uncaught TypeError: testObject.test is not a function
TestClass.test(); // Outputs: This is a static method

Inheritance: When a class gets its properties and methods from another class, it’s known as Inheritance. The inherited class is called a “child” and the class that is being inherited is called a “parent”. 

class TestClass {
  constructor(name,age) {
    this.name = name;
    this.age = age;
  }
  addAddress(address){
	this.address = address;
  }
  static  test(){
	console.log(“This is a static method”);
  }
}
class TestClass2 extends TestClass {
	constructor(name, age, gender) {
		super(name, age);
		this.gender=gender;
  }
} 
const testObject = new TestClass2(“TestUser”,25,”Male”);
console.log(testObject.name);  //Outputs: TestUser
console.log(testObject.gender); //Outputs: Male

Here, the name property is being extended from the parent and the gender property belongs to child class itself. Note that the child class must be instantiated in order to get the properties of the parent class.

Arrows

Arrows are a function shorthand for the normal functions. They are represented by => syntax. They are similar to normal function with an exception that normal functions take the scope of the object which calls it (document or window or an element ), but arrow functions take the scope of the object in which it is defined. 

class TestClass {
  constructor(name,age){
    this.name = name;
    this.age = age;
  }
 addAddress(address){
	this.address = address;
 }
changeAddress=>(address)=>this.address=address;
}

The changeAddress is specified as an arrow function that takes a parameter address. To know more about how the arrow functions can be used, refer to this post by MDN

Template Strings

This is easily one of my favorite features of ES6 so far. Template strings are an easy way of concatenating strings and (variables or object properties). They are enclosed inside backtick (` `) rather than single or double-quotes.

Expressions can be added to the strings by enclosing them inside curly braces with a dollar sign at the beginning ( ${expression} ).

let testString = “dog”;
console.log(“He has a ”+testString); //Normal concatenation using ‘+’ operator
console.log(`He has a ${testString}`); //Template String syntax

Templates string also provides various features. To know more, check out this page.

Destructuring

Destructing is a syntax that can be used to split an array or an object property, into separate variables.

//For arrays
let a,b,c,d;
[a,b,c,d]=[10,30,23,4];
  
//For objects
let testObject = {test1: “Test1”, test2:”Test2”};
let {test1, test2} = testObject; 
//Assigning default values to avoid undefined
const {test1 = 10, test2 = 20} = {test1:30};

In these examples, the variables are automatically assigned the corresponding array values. To avoid assigning undefined to variables, use default assignments.

let and const

You might probably be using these two declarations without knowing that they were introduced in ES6. let is almost similar to var except that the former has block scope and the latter has a global scope. const is used to declare variables whose values cannot be changed after they are initialized. 

//using var
console.log(somevariable); // undefined
var somevariable = 10; 
console.log(somevariable); // Outputs 10
//using let
console.log(somevariable); // Throws error saying somevariable is not defined
let somevariable = 10;
console.log(somevariable); // Does not execute since error has been thrown
//using const
const somevariable = 10;
console.log(somevariable); // Outputs 10
somevariable = 20; // throws error 

This doesn’t mean that let is not hoisted. It is hoisted but the difference is that it will not be initialized like var. Check out this awesome article on hoisting to have a clear understanding.

Generator Function

Normal functions, when called, always runs to completion i.e it can’t be paused until it finishes executing. But what if this is possible? Here’s where the Generator function shines bright. That’s not it. It can return something and can also resume from where it returned previously. Look at this example.

function *testFunction(x) {
  var y = (yield x);
  var z = y + (yield (x+10));
  return z;
}
var test = testFunction(10);  // Function should be called without the “*” 
console.log(test.next()); // Outputs:  {value: 10, done: false}
console.log(test.next(20)); // Outputs:  {value: 20, done: false}
console.log(test.next(30)); // Outputs:  {value: 50, done: true}

This is a basic example of a generator function. The syntax is function *function-name() or function* function-name, the position of the “*” is up to you. A generator function always yield values which also pauses the function execution. It always yields an object that has two properties: value (which returns the yielded value) and done (which indicates if the function has completed).

var test = testFunction(10);

Here, we have initialized value for the function since it receives a parameter “x”. We yield using the next() method and we can also throw an error using the throw() method. Since we have initialized already, we don’t need to pass a parameter to the first next() method and this yields (yield x) whose value is 10.

Now, when the parameter that is passed to the second next(20) method, it replaces the (yield x) and it becomes: var y = 20;

This yields (yield (x+10)) , in which x = 10 (as initialised) and so it returns 20.

Finally, when the third next(30) is invoked, (yield(x+10)) is replaced by 30 and so:

var z = y + (yield (x+10)); // y is 20 , z = 20 + 30 = 50

Note that if there is nothing to yield, the function takes the return statement by default and returns, also setting the done flag to true, indicating function completion.

Generator functions can also be used for:

  • Performing async operations (refer to this article to know more).
  • Error handling using throw() method (refer this article to know more.)

Part-1 Conclusion

This post has already gone long enough. That’s why I decided to split it into two parts. Make sure to read part-2 as well, in which I will be covering the rest of the features that you should definitely keep in mind while working on your project.

Make sure to refer to the articles that I have referenced for some of the features to get a better understanding. See you in part 2. Until then …

Arigato Gozaimasu 🙂

+1

28