Clear descriptions and comparisons of ES5 and ES6 features.

ECMAScript 2015, also known as ES6, introduced many changes to JavaScript. Here is an overview of some of the most common features and syntactical differences, with comparisons to ES5 where applicable.

Note: A commonly accepted practice is to use const except in cases of loops and reassignment. However, in this resource I'll be using let in place of var for all ES6 examples.

Legend

I'm not a fan of foo bar baz . Here is a key of most identifier names used throughout this reference.

Variable: x

Object: obj

Array: arr

Function: func

Parameter, method: a , b , c

, , String: str

Table of contents

Variable declaration

Constant declaration

Arrow function syntax

Template literals

Implicit returns

Key/property shorthand

Method definition shorthand

Destructuring (object matching)

Array iteration (looping)

Default parameters

Spread syntax

Classes/constructor functions

Inheritance

Modules - export/import

Promises/callbacks

Variables and constant feature comparison

I explain the concepts of scope and the differences between let , var , and const in the Understanding Variables, Scope, and Hoisting in JavaScript resource on DigitalOcean. This table provides a brief overview.

Keyword Scope Hoisting Can Be Reassigned Can Be Redeclared var Function scope Yes Yes Yes let Block scope No Yes No const Block scope No No No

Variable declaration

ES6 introduced the let keyword, which allows for block-scoped variables which cannot be hoisted or redeclared.

ES5

var x = 0

ES6

let x = 0

Constant declaration

ES6 introduced the const keyword, which cannot be redeclared or reassigned, but is not immutable.

ES6

const CONST_IDENTIFIER = 0

Arrow functions

The arrow function expression syntax is a shorter way of creating a function expression. Arrow functions do not have their own this , do not have prototypes, cannot be used for constructors, and should not be used as object methods.

ES5

function func ( a , b , c ) { } var func = function ( a , b , c ) { }

ES6

let func = ( a ) => { } let func = ( a , b , c ) => { }

Template literals

Concatenation/string interpolation

Expressions can be embedded in template literal strings.

ES5

var str = 'Release date: ' + date

ES6

let str = ` Release Date: ${ date } `

Multi-line strings

Using template literal syntax, a JavaScript string can span multiple lines without the need for concatenation.

ES5

var str = 'This text ' + 'is on ' + 'multiple lines'

ES6

let str = ` This text is on multiple lines `

Note: Whitespace is preserved in multi-line template literals. See Removing leading whitespace in ES6 template strings.

Implicit returns

The return keyword is implied and can be omitted if using arrow functions without a block body.

ES5

function func ( a , b , c ) { return a + b + c }

ES6

let func = ( a , b , c ) => a + b + c

Key/property shorthand

ES6 introduces a shorter notation for assigning properties to variables of the same name.

ES5

var obj = { a : a , b : b , }

ES6

let obj = { a , b , }

Method definition shorthand

The function keyword can be omitted when assigning methods on an object.

ES5

var obj = { a : function ( c , d ) { } , b : function ( e , f ) { } , }

ES6

let obj = { a ( c , d ) { } , b ( e , f ) { } , }

obj . a ( )

Destructuring (object matching)

Use curly brackets to assign properties of an object to their own variable.

var obj = { a : 1 , b : 2 , c : 3 }

ES5

var a = obj . a var b = obj . b var c = obj . c

ES6

let { a , b , c } = obj

Array iteration (looping)

A more concise syntax has been introduced for iteration through arrays and other iterable objects.

var arr = [ 'a' , 'b' , 'c' ]

ES5

for ( var i = 0 ; i < arr . length ; i ++ ) { console . log ( arr [ i ] ) }

ES6

for ( let i of arr ) { console . log ( i ) }

Default parameters

Functions can be initialized with default parameters, which will be used only if an argument is not invoked through the function.

ES5

var func = function ( a , b ) { b = b === undefined ? 2 : b return a + b }

ES6

let func = ( a , b = 2 ) => { return a + b }

func ( 10 ) func ( 10 , 5 )

Spread syntax

Spread syntax can be used to expand an array.

ES6

let arr1 = [ 1 , 2 , 3 ] let arr2 = [ 'a' , 'b' , 'c' ] let arr3 = [ ... arr1 , ... arr2 ] console . log ( arr3 )

Spread syntax can be used for function arguments.

ES6

let arr1 = [ 1 , 2 , 3 ] let func = ( a , b , c ) => a + b + c console . log ( func ( ... arr1 ) )

Classes/constructor functions

ES6 introducess the class syntax on top of the prototype-based constructor function.

ES5

function Func ( a , b ) { this . a = a this . b = b } Func . prototype . getSum = function ( ) { return this . a + this . b } var x = new Func ( 3 , 4 )

ES6

class Func { constructor ( a , b ) { this . a = a this . b = b } getSum ( ) { return this . a + this . b } } let x = new Func ( 3 , 4 )

x . getSum ( )

Inheritance

The extends keyword creates a subclass.

ES5

function Inheritance ( a , b , c ) { Func . call ( this , a , b ) this . c = c } Inheritance . prototype = Object . create ( Func . prototype ) Inheritance . prototype . getProduct = function ( ) { return this . a * this . b * this . c } var y = new Inheritance ( 3 , 4 , 5 )

ES6

class Inheritance extends Func { constructor ( a , b , c ) { super ( a , b ) this . c = c } getProduct ( ) { return this . a * this . b * this . c } } let y = new Inheritance ( 3 , 4 , 5 )

y . getProduct ( )

Modules - export/import

Modules can be created to export and import code between files.

index.html

< script src = " export.js " > </ script > < script type = " module " src = " import.js " > </ script >

export.js

let func = ( a ) => a + a let obj = { } let x = 0 export { func , obj , x }

import.js

import { func , obj , x } from './export.js' console . log ( func ( 3 ) , obj , x )

Promises represent the completion of an asynchronous function. They can be used as an alternative to chaining functions.

ES5 callback

function doSecond ( ) { console . log ( 'Do second.' ) } function doFirst ( callback ) { setTimeout ( function ( ) { console . log ( 'Do first.' ) callback ( ) } , 500 ) } doFirst ( doSecond )

ES6 Promise

let doSecond = ( ) => { console . log ( 'Do second.' ) } let doFirst = new Promise ( ( resolve , reject ) => { setTimeout ( ( ) => { console . log ( 'Do first.' ) resolve ( ) } , 500 ) } ) doFirst . then ( doSecond )

An example below using XMLHttpRequest , for demonstrative purposes only (Fetch API would be the proper modern API to use).

ES5 callback

function makeRequest ( method , url , callback ) { var request = new XMLHttpRequest ( ) request . open ( method , url ) request . onload = function ( ) { callback ( null , request . response ) } request . onerror = function ( ) { callback ( request . response ) } request . send ( ) } makeRequest ( 'GET' , 'https://url.json' , function ( err , data ) { if ( err ) { throw new Error ( err ) } else { console . log ( data ) } } )

ES6 Promise

function makeRequest ( method , url ) { return new Promise ( ( resolve , reject ) => { let request = new XMLHttpRequest ( ) request . open ( method , url ) request . onload = resolve request . onerror = reject request . send ( ) } ) } makeRequest ( 'GET' , 'https://url.json' ) . then ( ( event ) => { console . log ( event . target . response ) } ) . catch ( ( err ) => { throw new Error ( err ) } )

If you found this useful, please share!