Scripting language specification standardized by ECMA International.
Developed by Technical Committee 39 (TC-39).
| Name | Version | Coverage |
|---|---|---|
| IE 11, Edge 13, Edge 14 | 15%, 79%, 90% | |
| 49 | 93% | |
| 52 | 98% | |
| 39 | 98% | |
| 8, 9, 10 | 21%, 53%, 100% |
Unexpected value changes are a source of bugs.
var x = 3;
function func(randomize) {
if (randomize) {
var x = Math.random();
return x;
}
return x;
}
func(false);
undefined
var x = 3;
function func(randomize) {
var x;
if (randomize) {
x = Math.random();
return x;
}
return x;
}
func(false);
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs.push(function(){
console.log(i);
});
}
funcs[3]();
var i;
var funcs = [];
for (i = 0; i < 5; i++) {
funcs.push(function(){
console.log(i);
});
}
funcs[3]();
5
var x = 3;
function func(randomize) {
if (randomize) {
let x = Math.random();
return x;
}
return x;
}
func(false); //3
var x = 3;
function func(randomize) {
if (randomize) {
var x = Math.random();
return x;
}
return x;
}
func(false); //undefined
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs.push(function(){
console.log(i);
});
}
funcs[3](); //5
var funcs = [];
for (let i = 0; i < 5; i++){
funcs.push(function(){
console.log(i);
});
}
funcs[3](); //3
(function () { // open IIFE
var tmp = ···;
···
}()); // close IIFE
console.log(tmp);
{ // open block
let tmp = ···;
···
} // close block
console.log(tmp);
const foo;//SyntaxError
const a = 2;
console.log(a); //2
a = 3; //Uncaught TypeError
const a = [1, 2, 3];
a.push(4);
a.push(5);
console.log(a); // [1,2,3,4,5]
a = 42; //Uncaught TypeError: Assignment to constant variable.
const obj = {Id: 1};
obj.Name = "Walter";
console.log(obj); //Object {Id: 1, Name: "Walter"}
obj = {};//Uncaught TypeError: Assignment to constant variable.
var foo = function(x, y){
return x + y;
};
console.log(foo(1, 3)); //4
let foo = (x, y) => x + y;
console.log(foo(1, 3)); //4
function doSomething() {
var self = this;
setTimeout(function() {
self.start();
}, 500);
}
function doSomething() {
setTimeout(() => {
this.start();
}, 500);
}
let arr = [1, 2, 3];
foo(arr[0], arr[1], arr[2]); // 1 2 3
let arr = [1, 2, 3];
foo( ...arr );// 1 2 3
From apply() to the spread operator (... )
function foo(x, y, z) {
console.log( x, y, z );
}
let a = [1], b = [2, 3], c = [4];
let result = a.concat(b, c);
console.log(result);//[1,2,3,4]
let a = [1], b = [2, 3], c = [4];
let result = [...a, ...b, ...c];
console.log(result);//[1,2,3,4]
From concat() to the spread operator (... )
let nums = [-1, 11, 3];
Math.max(nums[0], nums[1], nums[2]);
Math.max.apply(null, nums);
let nums = [-1, 11, 3];
Math.max(...nums);// 11
function foo() {
console.log("first:", arguments[0]);
var rest = Array.prototype.slice.call(arguments, 1);
console.log("rest:", rest);
}
foo(1, 2, 3, 4, 5);
function foo(first, ...rest) {
console.log("first:", first);
console.log("rest:", rest);
}
foo(1, 2, 3, 4, 5);
// first: 1
// rest: [2, 3, 4, 5]
Lazily evaluated
function add (x, y){
x = x || 1;
y = y || 1;
console.log(x + y);
}
add(0, 4); //5 not 4
function add (x = 1, y = 1){
console.log(x + y);
}
add(undefined, 6); // 7
add(null, 6); // 6
=
ES5 Assignment
var arr = [1,2,3];
var a = arr[0], b = arr[1], c= arr[2];
var obj = {x: 4, y: 5, z: 6 }
var x = obj.x, y = obj.y, z = obj.z;
var obj = {x: 4, y: 5, z: 6 }
var a = obj.x, b = obj.y, c = obj.z;
ES6 Assignment
let [a,b,c] = [1,2,3];
let {x,y,z} = {x: 4, y: 5, z: 6 };
let {x:a, y:b, z:c} = {x:4, y:5, z:6};
Swap variables
[left, right] = [right, left]
Default values
let [ a = 3, b = 6, c = 9, d = 12 ] = [1, 2, 3];
let { x, y, z, w = 20 } = (() => ({ x: 4, y: 5, z: 6 }))();
Computed property
let key = "z"; let { [key]: foo } = { z: "bar" };
Rest items
let a = [2, 3, 4]; let [b, ... c] = a;
Named parameter
let o = { a: 1, b: 2, c: 3 };
function doSomething({b, a, c} = o){
console.log(a,b,c);
}
Complex structures
let obj = { x: { y: { z: 6 } } };
let { x: { y: { z: w } } } = obj;
ES5
function ES5Class(name){
this.name = name;
}
ES5Class.prototype.work = function(){
}
function ES5DerivedClass(name, title){
ES5Class.call(this, name);
this.title = title;
}
ES5DerivedClass.prototype = Object.create( ES5Class.prototype);
ES5DerivedClass.prototype.constructor = ES5Class;
ES5DerivedClass.prototype.work = function () {
ES5Class.prototype.work.call(this); //super call
// do more...
};
ES6
class ES6Class{
constructor(name){
this.name = name;
}
work(){
}
}
class ES6DerivedClass extends ES6Class{
constructor(name, title){
super(name);
this.title = title;
}
work(){
super.work();
//do more….
}
}
class Person {
constructor(name) {
this._name = name;
}
prototypeMethod() {
console.log(`prototype method`);
}
static staticMethod(){
console.log(`static method`);
}
get name() {
return this._name.toUpperCase();
}
set name(newName) {
this._name = newName;
}
}
class Employee extends Person {
constructor(name, title){
super(name);
this._title = title;
}
prototypeMethod() {
super.prototypeMethod();
console.log(`${this._name}, ${this._title}`);
}
}
let employee = new Employee("Rapth", "Developer");
employee.prototypeMethod();
var moduleName = (function () {
//private state
//private functions
return {
//public state
//public variables
};
})();
var es5Module = (function () {
var _privateProperty = 'Hello World';
function _privateMethod() {
console.log(_privateProperty);
};
return {
publicMethod: function() {
_privateMethod();
}
};
})();
Module Export
var es5Module = (function () {
var _privateProperty = 'Hello World';
var publicProperty = 'I am a public property';
function _privateMethod() {
console.log(_privateProperty);
}
function publicMethod() {
_privateMethod();
}
return {
publicMethod: publicMethod,
publicProperty: publicProperty
};
})();
Revealing Module Pattern
var es5Module = (function (myModule) {
var _privateProperty = 'Hello World';
var publicProperty = 'I am a public property';
function _privateMethod() {
console.log(_privateProperty);
}
myModule.publicMethod = function(){
_privateMethod();
}
return myModule;
})(es5Module || {});
Augment Module
var es5Module = (function () {
function greeting(name) {
console.log( "Hello " + name);
}
return {
greeting: greeting
};
})();
es5Module.greeting("Walter");
//es6Module.js
export function greeting(name){
console.log( "Hello " + name);
}
//app.js
import { greeting } from 'es6Module'
greeting("Walter");
ES5
ES6
//module.js
export function foo() {
console.log("foo");
}
export default function doSomething(){
console.log("default");
}
let awesome = 42;
let bar = [1, 2, 3];
let baz = {Id: 1, Name: "ABC"};
export { bar, awesome, baz as obj };
//app.js
import fnDefault, {foo as aliasFoo, bar, awesome, obj} from "module"
/* import fnDefault, * as es6Module from "module" */
fnDefault();
aliasFoo();
console.log(bar);
console.log(awesome);
console.log(obj);
Callback hell - N levels deep
function foo(finalCallback) {
request.get(url1, function(err1, res1) {
if (err1) { return finalCallback(err1); }
request.post(url2, function(err2, res2) {
if (err2) { return finalCallback(err2); }
request.put(url3, function(err3, res3) {
if (err3) { return finalCallback(err3); }
request.del(url4, function(err4, res4) {
// let's stop here
if (err4) { return finalCallback(err4); }
finalCallback(null, "whew all done");
})
})
})
})
}
Promise - 1 level deep
function foo() {
return request.getAsync(url1)
.then(function(res1) {
return request.postAsync(url2);
}).then(function(res2) {
return request.putAsync(url3);
}).then(function(res3) {
return request.delAsync(url4);
}).then(function(res4) {
return "whew all done";
});
}
| Callback | Promise |
|---|---|
| Is function | Is object |
| Is passed as arguments | Is returned |
| Handle success and failure | Don’t handle anything |
| Can represent multiple events | Can only represent one event |
let p = new Promise(function (resolve, reject) {
setTimeout(() => resolve(4), 2000);
});
p.then((res) => console.log(res)); //4
Generator + Promise: 0 level flat
function* foo() {
var res1 = yield request.getAsync(url1);
var res2 = yield request.getAsync(url2);
var res3 = yield request.getAsync(url3);
var res4 = yield request.getAsync(url4);
return "whew all done";
}
| Feature | Comparison with ES5 |
|---|---|
| Destructuring | 2x slower |
| Arrow Function | Identical |
| Default Parameter | Identical |
| Template Literal | 30x slower |
| Promise (with jquery 3.0) | 6x faster |
| Class | Identical |
JavaScript transpiler
ES6
ES5
const a = [1, 2, 3];
const a1 = input.map(item => item + 1);
"use strict";
var a = [1, 2, 3];
var a1 = input.map(function (item) {
return item + 1;
});
"devDependencies": {
"babel-core": "^6.9.1",
"babel-loader": "^6.2.4",
"babel-polyfill": "^6.9.1",
"babel-preset-es2015": "^6.9.0",
"webpack": "^1.13.1"
},
"scripts": {
"webpack": "webpack --watch"
},
var path = require('path');
module.exports = {
entry: {
userManager: "./Scripts/userManager.js"
},
output: {
path: path.resolve(__dirname, './'),
filename: './Bundle/[name].js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}
]
},
devtool: 'source-map'
};
package.json
webpack.config.js
npm run webpack
start
//Async function
async function main() {
let ret = await step1();
ret = await step2( ret );
ret = await Promise.all([
step3a( ret ),
step3b( ret ),
step3c( ret )]);
await step4( ret );
}
//object.observe(..)
let obj = { a: 1, b: 2 };
Object.observe(obj, function(changes){
for (var change of changes) {
console.log( change );
}
},
[ "add" , "update" , "delete"]
);
obj.c = 3;
// { name: "c", object: obj, type: "add" }
//Exponentiation operator
2 ** 3; //8
//Object property and ...
let o1 = { a: 1, b: 2 }, o2 = { c: 3 };
let o3 = { ... o1, ... o2, d: 4 };
console.log(o3.a, o3.b, o3.c, o3.d);
// 1 2 3 4
//destructured properties
let o1 = { b: 2, c: 3, d: 4 };
let { b, ... o2 } = o1;
console.log(b, o2.c, o2.d); // 2 3 4
//Array#includes(..)
let vals = [ "foo" , "bar" , 42, "baz" ];
if (vals.includes( 42 )) {
// found it!
}
//SIMD (Single Instruction Multiple Data)
var a = SIMD.Float32x4(1, 2, 3, 4);
var b = SIMD.Float32x4(5, 6, 7, 8);
var c = SIMD.Float32x4.add(a,b); // Float32x4[6,8,10,12]
[1] Kyle Simpson, You Don’t Know JS: ES6 and Beyond, O’Reilly, 2015
[2] http://es6-features.org/
[3] http://exploringjs.com/es6/
[4] https://leanpub.com/understandinges6/read
[5] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
[6] http://www.html5rocks.com/en/tutorials/es6/promises/