Best New Features in ECMAScript 6
17/04/2016 11:58
ECMAScript (the language that JavaScript is based on) is currently undergoing its first major upgrade since 2009. Here's an overview of the most important changes coming in ECMAScript 6... As decided by... well... me.
It won't be long before all features of ECMAScript 6 are available in every modern browser but until then, you should be able to use most, if not all of the features mentioned below in the latest version of Chrome, Firefox and Edge. For detailed information about what features are supported by specific versions of a browser take a look here.
This post is by no means an exhaustive list of the changes coming in ECMAScript 6 but should provide some insight into some of the more important ones. For information about the other changes check here.
Classes
JavaScript started out life being used as a means to add small bits of interactive and dynamic content to websites but quickly moved to being used on larger and larger projects; both inside and out of the browser. Projects such as Node.js have enabled JavaScript to be used for pretty much anything that any other server side language would be used for and have only expedited the need for features that enable it to scale to use on large projects.
Now you may argue that JavaScript can already approximate classes in many respects and that is true. In fact classes in ECMAScript 6 are just syntactic sugar for a popular method of emulating classes in JavaScript. The problem is that there is no clean cut way of defining a type which has lead to a variety of different techniques that each have pro's and cons in different situations. This post highlights the problem but there are many more ways of defining classes in JavaScript and this makes it difficult both to learn and to remain consistent on large code bases where many developers work on the code.
So anyway, without further ado, here's a comparison between the new class syntax and one of the methods of achieving a similar result in ES5.
ECMAScript6
//Defining the class class Car { constructor(name, topSpeed) { this.name = name; this.topSpeed = topSpeed; } accelerate() { console.log("I'm accelerating to " this.topSpeed); } } //Instantiating a class and calling a method. var fastCar = new Car("SuperFastCar", 200); fastCar.accelerate();
ECMAScript5
//Defining the class var Car = (function () { function Car(name, topSpeed) { this.name = name; this.topSpeed = topSpeed; } Car.prototype.accelerate = function () { console.log("I'm accelerating to " this.topSpeed); }; return Car; })(); //Instantiating the class and calling a method. var fastCar = new Car("SuperFastCar", 200); fastCar.accelerate();
So that's already looking quite a bit clearer than it used to, but what about extending a class. Let's make the car a bit safer by adding some brakes.
ECMAScript6
class SafeCar extends Car { //Extends keyword enables inheritance constructor(name, topSpeed, brakeSpeed) { super(name, topSpeed); //Call the parent constructor with the super method this.brakeSpeed = brakeSpeed; } brake(){ console.log("I'm now braking at " this.brakeSpeed "mph!"); } }
ECMAScript5
var SafeCar = (function () { function SafeCar(name, topSpeed, brakeSpeed) { // Call the parent constructor var car = new Car("SuperFastCar", 200); SafeCar.prototype = car.prototype; this.brakeSpeed = brakeSpeed; } // Add brake method SafeCar.prototype.brake = function(){ console.log("I'm now braking at " this.brakeSpeed "mph!"); } } })();
So as you can see, the new class, constructor and extends keywords that have been added in ECMAScript6 finally add a standard way to define classes in ECMAScript. I think most people would agree that new method is more clear than it was previously, if you prefer to use one of the old methods then fear not, you can still do that too.
Promises
Template Strings
This is similar to C# string interpolation in that it allows you to enter variables directly into a string and have the text replaced with their values. The syntax is slightly different from C# but the idea is the same. Template strings need to be surrounded with backticks rather than double or single quotes - that's the ` character. Variables within template strings should be written as ${variableName}. Here are a few examples.
ECMAScript6
var name = "slimShady"; var age = "50"; // Variables and expressions in strings. console.log(`Hi, my name is ${name} and I'm ${age} years old but i feel ${age / 2}`); // Would print the string: // Hi, my name is slimShady and I'm 50 years old but i feel 25 // Multiline strings console.log(` <html> <head> <title>This is a multiline string</title> </head> <body> </body> </html>`); // Would print the string: //<html> // <head> // <title>This is a multiline string</title> // </head> // <body> // </body> //</html>
ECMAScript5
var name = "slimShady"; var age = "50"; //Variables and expressions in strings. console.log("Hi, my name is " + name + " and I'm " + age + " years old but i feel " + (age / 2)); // Would print the string: // Hi, my name is slimShady and I'm 50 years old but i feel 25 // Multiline strings console.log("<html>\n<head>\n<title>This is a multiline string</title>\n</head>\n<body>\n</body>\n</html>"); // Would print the string: //<html> // <head> // <title>This is a multiline string</title> // </head> // <body> // </body> //</html>
for-of Operator
Most modern languages have a for-in operator and JavaScript has one too but it's different. You see in most languages the for-in operator will loop over each item in a collection but for some reason, the designers of ECMAScript decided to be different. They decided to make for-in loop over the name of each of the properties of an object instead of the far more common use case catered for by other languages. Why you ask? Maybe the designers took a group trip to the ashram of Maharishi Yogi that day and they were able to see reality from a perspective where this would be a good decision... I don't know but for better of for worse, this is the state we're in - or at least it was until ECMAScript 6 came to the rescue with the for-of operator. Here's an example to show the difference between the two operators.
for-in operator
var collection = [5, 7, 10]; collection.foo = "hello" for(var item in collection) { console.log(item); } // Would log: 0, 1, 2, foo // Notice that's the variable foo's name not even it's value.
for-of operator
var collection = [5, 7, 10]; collection.foo = "hello" for(var item of collection) { console.log(item); } // Would log: 5, 7, 10 // ...like a sane person