Below is a list of the top ten ES6 features (ranked first and last):
- Default Parameters (default parameter) in ES6
- Template Literals (Template Text) in ES6
- Multi-line Strings (multi-line string) in ES6
- Destructuring Assignment in ES6
- Enhanced Object Literals (Enhanced Object Text) in ES6
- Arrow Functions in ES6
- Promises in ES6
- Block-Scoped Constructs Let and Const
- Classes (class) in ES6
- Modules in ES6
[Remarks] Only 10 of the more common features are listed here.Not all browsers support the ES6 module, so you need to use something like jspm to support the ES6 module.
1.Default Parameters (default parameter)
ES5:
var link = function (height, color, url) {
var height = height || 50;
var color = color || 'red';
var url = url || 'http://azat.co';
...
}
ES6: Write directly in parameters
var link = function(height = 50, color = 'red', url = 'http://azat.co') {
...
}
Benefits save code.
2.Template Literals (Template Object)
Output variable inside string
ES5:
var name = 'Your name is ' + first + ' ' + last + '.';
var url = 'http://localhost:3000/api/messages/' + id;
ES6: Use the new syntax ${NAME} and put it in quotation marks:
var name = 'Your name is ${first} ${last}.';
var url = 'http://loalhost:3000/api/messages/${id}';
Benefit: Here, ${NAME} is used directly as a string without writing a plus sign
3.Multi-line Strings
ES5:
var roadPoem = 'Then took the other, as just as fair,nt'
+ 'And having perhaps the better claimnt'
+ 'Because it was grassy and wanted wear,nt'
+ 'Though as for that the passing therent'
+ 'Had worn them really about the same,nt';
var fourAgreements = 'You have the right to be you.n
You can only be you when you do your best.';
ES6: Inverse quotation marks are OK!
var roadPoem = `Then took the other, as just as fair,
And having perhaps the better claim
Because it was grassy and wanted wear
Though as for that the passing theren
Had worn them really about the same,`;
var fourAgreements = `You have the right to be you.n
You can only be you when you do your best.`;
Benefits: A direct inversion quote, all the strings can be put in, and the intermediary is free to wrap, which is refreshing!
4.Destructuring Assignment
In the following example, house and mouse are key s, and house and mouse are also variables.
ES5:
var data = $('body').data(), // data has properties house and mouse
house = data.house,
mouse = data.mouse;
And with ES5 in node.js:
var jsonMiddleware = require('body-parser').jsonMiddleware ;
var body = req.body, // body has username and password
username = body.username,
password = body.password;
ES6:
var {house,mouse} = $('body').data(); //we'll get house and mouse variables
var {jsonMiddleware} = require('body-parser');
var {username,password} = req.body;
In the array, this is true:
var [col1,col2] = $('.column'),
[line1,line2,line3, ,line5] = file.split('n');
Benefit: Using {} eliminates the step of writing an object's properties, although the variable in this {} is consistent with the object's property name.
5.Enhanced Object Literals
There are many unexpected things you can do with object text!With ES6, we can bring JSON in ES5 closer to a class.
Here is a typical example ES5 Object text, which contains methods and properties:
var serviceBase = {port: 3000, url: 'azat.co'},
getAccounts = function(){return [1,2,3]};
var accountServiceES5 = {
port: serviceBase.port,
url: serviceBase.url,
getAccounts: getAccounts,
toString: function() {
return JSON.stringify(this.valueOf());
},
getUrl: function() {return "http://" + this.url + ':' + this.port},
valueOf_1_2_3: getAccounts()
}
If we want it to be more interesting, we can use itObject.create from serviceBase How to inherit the prototype:
var accountServiceES5ObjectCreate = Object.create(serviceBase)
// The Object.create() method creates an object with the specified prototype and several specified properties.
var accountServiceES5ObjectCreate = {
getAccounts: getAccounts,
toString: function() {
return JSON.stringify(this.valueOf());
},
getUrl: function() {return "http://" + this.url + ':' + this.port},
valueOf_1_2_3: getAccounts()
}
In the object text of ES6: either getAccounts: getAccounts can be assigned directly or only one getAccounts can be used
var serviceBase = {port: 3000, url: 'azat.co'},
getAccount = function(){return [1,2,3]};
var accountService = {
__proto__: serviceBase, //Setting properties through proto
getAccount, // Either getAccounts can be assigned directly: getAccounts, or only one getAccounts can be used
toString() { //Change json form to function form here
return JSON.stringify(super.valueOf());
//Call super guard
},
getUrl() {return "http://" + this.url + ':' + this.port},
[ 'valueOf_' + getAccounts().join('_') ]: getAccounts() //Convert the array [1,2,3] from the getAccounts() method to the string 1_2_3 here using the dynamic key value (valueOf_1_2_3)
};
console.log(accountService);
Benefit: Equivalent to writing results directly in instead of requiring key:value
- Change the json form of toString: function(){} into a function (class) like toString(){}
- Either you can directly assign a json like getAccounts: getAccounts, or you can just use one getAccounts to express the same meaning
6.Arrow Functions in
These rich arrows are surprising because they make a lot of things happen, like,
Previously when we used closures, this always changed unexpectedly, but the beauty of the arrow function is that now your this can be used as you expected, and inside the arrow function, this is still what it was.
ES5:
var _this = this;
$('.btn').click(function(event){
_this.sendData();
})
ES6: You don't need to use _this = this:
$('.btn').click((event) =>{
this.sendData();
})
Another example is:
ES5:
var logUpperCase = function() {
var _this = this; //this = Object {string: "ES6 ROCKS"}
console.log('this Refer to',this); //Object {string: "ES6 ROCKS"}
console.log('_this Refer to',_this);//Object {string: "ES6 ROCKS"}
this.string = this.string.toUpperCase();
console.log(_this.string); //ES6 ROCKS
console.log(this.string); //ES6 ROCKS
return function () {
return console.log(_this.string); //ES6 ROCKS
return console.log(_this.string); //If return _this.string, undefined is returned because
}
}
logUpperCase.call({ string: 'ES6 rocks' })();
ES6: We don't need to waste time with _this. Now your this can be used as you expected. In the arrow function, this is still the original one
var logUpperCase = function() {
this.string = this.string.toUpperCase();//thisOr the originalthis
return () => console.log(this.string);
}
logUpperCase.call({ string: 'ES6 rocks' })();
Note that in ES6=>you can mix and match old functions if you want.When an arrow function is used in a line of code, it becomes an expression.It will secretly return the result of a single statement.If you exceed one line, you will need to explicitly use return.
ES5:
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9'];
var messages = ids.map(function (value) {
return "ID is " + value; // explicit return
});
ES6:
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9'];
var messages = ids.map((value) => `ID is ${value}`); //implicit return
Benefits:
*There's no need to waste time with _this, now your this can be used as you expected, and in the arrow function, this is still what it was.
* => can be used instead of the function keyword. When an arrow function is used on a line, you can omit {} or return, which will be returned implicitly.
7.Promises
ES5:
setTimeout(function(){
console.log('Yay!');
}, 1000);
ES6: We can override it with promise
var wait1000 = new Promise((resolve,reject)=> {
setTimeout(resolve,1000);
}).then(()=> {
console.log('Yay!');
});
If we had more nested logic in the setTimeout() callback function, the benefit would be obvious:
ES5:
setTimeout(function(){
console.log('Yay!');
setTimeout(function(){
console.log('Wheeyee!');
}, 1000)
}, 1000);
ES6: We can override it with promise
var wait1000 = ()=> new Promise((resolve,reject)=>{ setTimeout(resolve,1000);});
wait1000()
.then(function(){
console.log('Yay!');
return wait1000()
})
.then(function(){
console.log('Wheeyee!');
});
8 Block-Scoped (Block Scope and Construct let s and const s)
let is a new way of declaring variables that allows you to control the scope of variables at the block level.We define code blocks in curly brackets, and in ES5, block-level scopes do nothing:
function calculateTotalAmount (vip) {
var amount = 0;
if (vip) {
var amount = 1;
}
{ // more crazy blocks!
var amount = 100;
{
var amount = 1000;
}
}
return amount;
}
console.log(calculateTotalAmount(true)); // 1000
ES6: Restrict block-level scope with let
function calculateTotalAmount(vip){
var amouont = 0; // probably should also be let, but you can mix var and let
if (vip) {
let amount = 1; // first amount is still 0
}
{ // more crazy blocks!
let amount = 100; // first amount is still 0
{
let amount = 1000; // first amount is still 0
}
}
return amount;
}
console.log(calculateTotalAmount(true)); //0 Because there are blocks in the scopelet.
When it comes to const, it's easier; it's a variable and a block-level scope, like a let.
Benefit: We use let to limit block-level scope.var is the limit function scope.
9. Classes (Classes)
ES6 does not use functions, but implements classes using prototypes.We create a class, baseModel, in which a constructor and a getName() method are defined:
class baseModel {
constructor(options, data) {// class constructor, Note that we haveoptions anddataDefault parameter values are used.
this.name = 'Base';
this.url = 'http://azat.co/api';
this.data = data;
this.options = options;
}
getName() { // class method
console.log(`Class name: ${this.name}`);
}
getUrl() { // class method
console.log(`Url: ${this.url}`);
}
}
AccountModel inherits from the class baseModel:
class AccountModel extends baseModel {
constructor(options, data) {
super({private: true}, ['32', '5242']);
this.url +='/accounts/';
}
get accountsData() {
return this.data;
}
}
// call
let accounts = new AccountModel(5);
accounts.getName(); // Class name: Base
console.log('Data is %s', accounts.accountsData);
// Data is 32,5242
//The subclass must call the super method in the constructor method, or an error will be reported when creating a new instance.
//This is because subclasses do not have their own this object, but inherit and process the parent's this object.
//If you do not call the super method, the subclass will not get the this object.
[Note]
*In inheritance here, the subclass must call the super method in the constructor method, otherwise an error will be reported when creating a new instance.
*The super method here inherits all the methods of the parent class, including those not in the parent's constructor. Of course, it can override the parent method, such as the example above, which inherits properties such as getName(),getUrl() and this.name in constructor(), as well as overwriting this.url and adding accountsData.And the new method must be preceded by get.
*The subclass calls the super method to pass in parameters that correspond to the parameters of the constructor() function.
10. Modules (Modules)
ES5 export:
module.exports = { port: 3000, getAccounts: function() { ... }}
ES6 export:
export var port = 3000;
export function getAccounts(url) { ...}
ES5 Import:
var service = require('module.js');
console.log(service.port); // 3000
ES6 Import:
We need to use import {name} from'my-module'syntax
import {port, getAccounts} from 'module';
console.log(port); // 300
Or ES6 import as a whole:
import * as service from 'module';
console.log(service.port); // 3000
There are many other features of ES6 that you may want to use, ranked first and foremost:
- New Math, Number, String, Array and Object methods
- Binary and Octal Data Types
- Default parameter indefinite parameter extension operator
- Symbols symbol
- tail call
- Generators
- New data structures like Map and Set (new data construction objects like MAP and set)