JavaScript ES6+
Meabed
Posted on July 6, 2019
I have written this post while I was preparing for my talk at ME.IO JS meetup, and I thought its good to share it as it cloud help or guide someone searching for or reading it.
JavaScript History:
- 1995: JavaScript is born as LiveScript
- 1997: ECMAScript standard is established
- 1999: ES3 comes out and IE5 is all the rage
- 2000–2005: XMLHttpRequest, a.k.a. AJAX, gains popularity in app such as Outlook Web Access (2000) and Oddpost (2002), Gmail (2004) and Google Maps (2005).
- 2009: ES5 comes out (this is what most of us use now) with forEach, Object.keys, Object.create and standard JSON
- 2015: ES6/ECMAScript2015 comes out; it has mostly syntactic sugar, because people weren’t able to agree on anything more ground breaking
- 2016: ES7, 2017: ES8, 2018: ES9… ES.Next
Gist links to the code:
10 ES6 Features:
I won't be covering all JS ES6+ features in this post, i will cover top 10 features IMO :) - please feel free to comment, discusses, suggest more.
1. Default Parameters in ES6
// ES5
var link = function (height, color, url) {
var height = height || 50
var color = color || 'red'
var url = url || 'http://google.com'
...
}
// ES6
var link = function(height = 50, color = 'red', url = 'http://google.com') {
...
}
2. Template Literals in ES6
// ES5
var name = 'Your name is ' + first + ' ' + last + '.'
var url = 'http://localhost:3000/api/messages/' + id
// ES6
var name = `Your name is ${first} ${last}.`
var url = `http://localhost:3000/api/messages/${id}`
3. Multi-line Strings in ES6
// ES5
var roadPoem = 'Then took the other, as just as fair,\n\t'
+ 'And having perhaps the better claim\n\t'
+ 'Because it was grassy and wanted wear,\n\t'
+ 'Though as for that the passing there\n\t'
+ 'Had worn them really about the same,\n\t'
var fourAgreements = 'You have the right to be you.\n\
You can only be you when you do your best.'
// ES6
var roadPoem = `Then took the other, as just as fair,
And having perhaps the better claim
Because it was grassy and wanted wear`
var fourAgreements = `You have the right to be you.
You can only be you when you do your best.`
4. Destructuring Assignment in ES6
// ES5
var data = $('body').data() // data has properties house and mouse
var house = data.house
var mouse = data.mouse
// ES6
var {house, mouse} = $('body').data() // we'll get house and mouse variables
// ES5
var jsonMiddleware = require('body-parser').json
var body = req.body, // body has username and password
username = body.username,
password = body.password
// ES6
var {json: jsonMiddleware} = require('body-parser')
var {username, password} = req.body
// ES6
var [col1, col2] = $('.column'),
[line1, line2, line3, , line5] = file.split('\n')
// ES6
const myObject = {
one: 'a',
two: 'b',
three: 'c'
};
const { one, two, three } = myObject;
// one = 'a', two = 'b', three = 'c'
// ES6
const myObject = {
one: 'a',
two: 'b',
three: 'c'
};
const { one: first, two: second, three: third } = myObject;
// first = 'a', second = 'b', third = 'c'
5. Enhanced Object Literals in ES6
// ES5
function getLaptop(make, model, year) {
return { make: make, model: model, year: year }
}
getLaptop("Apple", "MacBook", "2015");// {make: "Apple", model: "MacBook", year: "2015"}
// ES6
function getLaptop(make, model, year) {
return { make, model, year }
}
getLaptop("Apple", "MacBook", "2015"); // {make: "Apple", model: "MacBook", year: "2015"}
// ES5
function getLaptop(make, model, year) {
return {
sayModel : function() {
return model;
}
}
}
getLaptop("Apple", "MacBook", "2015").sayModel(); //"MacBook"
// ES6
function getLaptop(make, model, year) {
return{
sayModel() {
return model;
}
}
}
getLaptop("Apple", "MacBook", "2015").sayModel(); //"MacBook"
// ES5
var key1 = 'one',
obj = {
two: 2,
three: 3
};
obj[key1] = 1;
// obj.one = 1, obj.two = 2, obj.three = 3
// ES6
const key1 = 'one',
obj = {
[key1]: 1,
two: 2,
three: 3
};
// obj.one = 1, obj.two = 2, obj.three = 3
// ES6
const i = 1,
obj = {
['i' + i]: i
};
console.log(obj.i1); // 1
// ES6
const i = 2,
obj = {
['mult' + i]: x => x * i
};
console.log( obj.mult2(5) ); // 10
ES2018 (ES9) Rest/Spread Properties
const myObject = { a: 1, b: 2, c: 3 };
const { a, ...x } = myObject;
// a = 1, x = { b: 2, c: 3 }
restParam({ a: 1, b: 2, c: 3 });
function restParam({ a, ...x }) {
// a = 1
// x = { b: 2, c: 3 }
}
const obj1 = { a: 1, b: 2, c: 3 },
obj2 = { ...obj1, z: 26 };
// obj2 is { a: 1, b: 2, c: 3, z: 26 }
ES2018 (ES9) rest/spread property support is patchy, but it’s available in Chrome, Firefox and Node.js 8.6+.
6. Arrow Functions in ES6
Main benefit: No binding of ‘this’
// ES5 Callback functions with dynamic context
var _this = this
$('.btn').click(function(event){
_this.sendData()
})
// ES6 Callback functions with dynamic context
$('.btn').click((event) =>{
this.sendData()
})
var cat = {
lives: 9,
jumps: () => {
this.lives--;
}
}
// implicit return
() => 42
// In fact, you don’t even need the parentheses!
_ => 42
x => 42 || (x) => 42
// explict return
var addValues = (x, y) => {
return x + y
}
// wrap in parentheses to return object literal
x =>({ y: x })
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9']
var messages = ids.map(function (value) {
return "ID is " + value // explicit return
})
var ids = ['5632953c4e345e145fdf2df8','563295464e345e145fdf2df9']
var messages = ids.map(value => `ID is ${value}`) // implicit return
7. Promises in ES6
A promise represents the eventual result of an asynchronous operation.
There were a lot of promise implementations with slightly different syntax. q, bluebird, deferred.js, vow, avow, jquery deferred etc..., ES6 has a standard Promise
implementation
setTimeout(function(){
console.log('Yay!')
}, 1000)
var wait1000 = new Promise((resolve, reject)=> {
setTimeout(resolve, 1000)
}).then(()=> {
console.log('Yay!')
})
setTimeout(function(){
console.log('Yay!')
setTimeout(function(){
console.log('Wheeyee!')
}, 1000)
}, 1000)
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 Constructs Let and Const
let
to restrict the scope to the blocks. Vars
are function scoped, const
it an immutable, and it’s also block-scoped like let
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))
// The result will be 1000
function calculateTotalAmount (vip) {
var amount = 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))
// The result will be 0
function calculateTotalAmount (vip) {
const amount = 0
if (vip) {
const amount = 1
}
{ // more crazy blocks!
const amount = 100
{
const amount = 1000
}
}
return amount
}
console.log(calculateTotalAmount(true))
// The result will be 0
9. Classes in ES6
class baseModel {
// default params
constructor(options = {}, data = []) { // class constructor
this.name = 'Base'
this.url = 'http://azat.co/api'
this.data = data
this.options = options
}
// no need function keyword and ":"
getName() { // class method
console.log(`Class name: ${this.name}`)
}
}
class AccountModel extends baseModel {
constructor(options, data) {
super({private: true}, ['32113123123', '524214691']) //call the parent method with super
this.name = 'Account Model'
this.url +='/accounts/'
}
get accountsData() { //calculated attribute getter
// ... make XHR
return this.data
}
}
let accounts = new AccountModel(5)
accounts.getName()
console.log('Data is %s', accounts.accountsData)
Class name: Account Model
Data is %s 32113123123,524214691
10. Modules in ES6
There were no native modules support in JavaScript before ES6. People came up with AMD, RequireJS, CommonJS and other workarounds. Now there are modules with import
and export
operands
// ES5 `module.js`
module.exports = {
port: 3000,
getAccounts: function() {
...
}
}
// ES5 `main.js`
var service = require('module.js')
console.log(service.port) // 3000
// ES6 `module.js`
export var port = 3000
export function getAccounts(url) {
...
}
// ES6 file `main.js`
import {port, getAccounts} from 'module'
console.log(port) // 3000
// OR
import * as service from 'module'
console.log(service.port) // 3000
If you have any other useful ideas or suggestion to enhance productivity or keep your system up to date, I would love to hear it and share it, please feel free to leave it in the comment or @meabed
Happy coding 🤞
Posted on July 6, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024