Fork me on GitHub Tweet 0
ES6
ECMAScript 6 — New Features: Overview & Comparison
See how cleaner and more concise
your JavaScript code can look and
start coding in ES6 now !!
"A good programming language is a
conceptual universe for thinking
about programming." — Alan J. Perlis
Constants
Constants
Support for constants (also known as "immutable variables"), i.e., variables which cannot be re-assigned new content. Notice: this only makes the variable itself immutable, not its assigned content (for instance, in case the content is an object, this means the object itself can still be altered).
ECMAScript 6 — syntactic sugar: reduced | traditional
const PI = 3.141593; PI > 3.0;
ECMAScript 5 — syntactic sugar: reduced | traditional
// only in ES5 through the help of object properties // and only in global context and not in a block scope Object.defineProperty(typeof global === "object" ? global : window, "PI", { value: 3.141593, enumerable: true, writable: false, configurable: false }) PI > 3.0;
Scoping
Block-Scoped Variables
Block-scoped variables (and constants) without hoisting.
ECMAScript 6 — syntactic sugar: reduced | traditional
for (let i = 0; i < a.length; i++) { let x = a[i]; } for (let i = 0; i < b.length; i++) { let y = b[i]; } let callbacks = []; for (let i = 0; i <= 2; i++) { callbacks[i] = function () { return i * 2; }; } callbacks[0]() === 0; callbacks[1]() === 2; callbacks[2]() === 4;
ECMAScript 5 — syntactic sugar: reduced | traditional
var i, x, y; for (i = 0; i < a.length; i++) { x = a[i]; } for (i = 0; i < b.length; i++) { y = b[i]; } var callbacks = []; for (var i = 0; i <= 2; i++) { (function (i) { callbacks[i] = function() { return i * 2; }; })(i); } callbacks[0]() === 0; callbacks[1]() === 2; callbacks[2]() === 4;
Scoping
Block-Scoped Functions
Block-scoped function definitions.
ECMAScript 6 — syntactic sugar: reduced | traditional
{ function foo () { return 1; } foo() === 1; { function foo () { return 2; } foo() === 2; } foo() === 1; }
ECMAScript 5 — syntactic sugar: reduced | traditional
// only in ES5 with the help of block-scope emulating // function scopes and function expressions (function () { var foo = function () { return 1; } foo() === 1; (function () { var foo = function () { return 2; } foo() === 2; })(); foo() === 1; })();
Arrow Functions
Expression Bodies
More expressive closure syntax.
ECMAScript 6 — syntactic sugar: reduced | traditional
odds = evens.map(v => v + 1); pairs = evens.map(v => ({ even: v, odd: v + 1 })); nums = evens.map((v, i) => v + i);
ECMAScript 5 — syntactic sugar: reduced | traditional
odds = evens.map(function (v) { return v + 1; }); pairs = evens.map(function (v) { return { even: v, odd: v + 1 }; }); nums = evens.map(function (v, i) { return v + i; });
Arrow Functions
Statement Bodies
More expressive closure syntax.
ECMAScript 6 — syntactic sugar: reduced | traditional
nums.forEach(v => { if (v % 5 === 0) fives.push(v); })
ECMAScript 5 — syntactic sugar: reduced | traditional
nums.forEach(function (v) { if (v % 5 === 0) fives.push(v); });
Arrow Functions
Lexical this
More intuitive handling of current object context.
ECMAScript 6 — syntactic sugar: reduced | traditional
this.nums.forEach((v) => { if (v % 5 === 0) this.fives.push(v); });
ECMAScript 5 — syntactic sugar: reduced | traditional
// variant 1 var self = this; this.nums.forEach(function (v) { if (v % 5 === 0) self.fives.push(v); }); // variant 2 (since ECMAScript 5.1 only) this.nums.forEach(function (v) { if (v % 5 === 0) this.fives.push(v); }.bind(this));
Extended Parameter Handling
Default Parameter Values
Simple and intuitive default values for function parameters.
ECMAScript 6 — syntactic sugar: reduced | traditional
function f (x, y = 7, z = 42) { return x + y + z; } f(1) === 50;
ECMAScript 5 — syntactic sugar: reduced | traditional
function f (x, y, z) { if (y === undefined) y = 7; if (z === undefined) z = 42; return x + y + z; }; f(1) === 50;
Extended Parameter Handling
Rest Parameter
Aggregation of remaining arguments into single parameter of variadic functions.
ECMAScript 6 — syntactic sugar: reduced | traditional
function f (x, y, ...a) { return (x + y) * a.length; } f(1, 2, "hello", true, 7) === 9;
ECMAScript 5 — syntactic sugar: reduced | traditional
function f (x, y) { var a = Array.prototype.slice.call(arguments, 2); return (x + y) * a.length; }; f(1, 2, "hello", true, 7) === 9;
Extended Parameter Handling
Spread Operator
Spreading of elements of an iterable collection (like an array or even a string) into both literal elements and individual function parameters.
ECMAScript 6 — syntactic sugar: reduced | traditional
var params = [ "hello", true, 7 ]; var other = [ 1, 2, ...params ]; // [ 1, 2, "hello", true, 7 ] f(1, 2, ...params) === 9; var str = "foo"; var chars = [ ...str ]; // [ "f", "o", "o" ]
ECMAScript 5 — syntactic sugar: reduced | traditional
var params = [ "hello", true, 7 ]; var other = [ 1, 2 ].concat(params); // [ 1, 2, "hello", true, 7 ] f.apply(undefined, [ 1, 2 ].concat(params)) === 9; var str = "foo"; var chars = str.split(""); // [ "f", "o", "o" ]
Template Literals
String Interpolation
Intuitive expression interpolation for single-line and multi-line strings. (Notice: don't be confused, Template Literals were originally named "Template Strings" in the drafts of the ECMAScript 6 language specification)
ECMAScript 6 — syntactic sugar: reduced | traditional
var customer = { name: "Foo" }; var card = { amount: 7, product: "Bar", unitprice: 42 }; var message = `Hello ${customer.name}, want to buy ${card.amount} ${card.product} for a total of ${card.amount * card.unitprice} bucks?`;
ECMAScript 5 — syntactic sugar: reduced | traditional
var customer = { name: "Foo" }; var card = { amount: 7, product: "Bar", unitprice: 42 }; var message = "Hello " + customer.name + ",\n" + "want to buy " + card.amount + " " + card.product + " for\n" + "a total of " + (card.amount * card.unitprice) + " bucks?";
Template Literals
Custom Interpolation
Flexible expression interpolation for arbitrary methods.
ECMAScript 6 — syntactic sugar: reduced | traditional
get`http://example.com/foo?bar=${bar + baz}&quux=${quux}`;
ECMAScript 5 — syntactic sugar: reduced | traditional
get([ "http://example.com/foo?bar=", "&quux=", "" ],bar + baz, quux);
Template Literals
Raw String Access
Access the raw template string content (backslashes are not interpreted).
ECMAScript 6 — syntactic sugar: reduced | traditional
function quux (strings, ...values) { strings[0] === "foo\n"; strings[1] === "bar"; strings.raw[0] === "foo\\n"; strings.raw[1] === "bar"; values[0] === 42; } quux `foo\n${ 42 }bar` String.raw `foo\n${ 42 }bar` === "foo\\n42bar";
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Extended Literals
Binary & Octal Literal
Direct support for safe binary and octal literals.
ECMAScript 6 — syntactic sugar: reduced | traditional
0b111110111 === 503; 0o767 === 503;
ECMAScript 5 — syntactic sugar: reduced | traditional
parseInt("111110111", 2) === 503; parseInt("767", 8) === 503; 0767 === 503; // only in non-strict, backward compatibility mode
Extended Literals
Unicode String & RegExp Literal
Extended support using Unicode within strings and regular expressions.
ECMAScript 6 — syntactic sugar: reduced | traditional
"𠮷".length === 2; "𠮷".match(/./u)[0].length === 2; "𠮷" === "\uD842\uDFB7"; "𠮷" === "\u{20BB7}"; "𠮷".codePointAt(0) == 0x20BB7; for (let codepoint of "𠮷") console.log(codepoint);
ECMAScript 5 — syntactic sugar: reduced | traditional
"𠮷".length === 2; "𠮷".match(/(?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF][\uD800-\uDBFF][\uDC00-\uDFFF][\uD800-\uDBFF](?![\uDC00-\uDFFF])(?:[^\uD800-\uDBFF]^)[\uDC00-\uDFFF])/)[0].length === 2; "𠮷" === "\uD842\uDFB7"; // no equivalent in ES5 // no equivalent in ES5 // no equivalent in ES5
Enhanced Regular Expression
Regular Expression Sticky Matching
Keep the matching position sticky between matches and this way support efficient parsing of arbitrary long input strings, even with an arbitrary number of distinct regular expressions.
ECMAScript 6 — syntactic sugar: reduced | traditional
let parser = (input, match) => { for (let pos = 0, lastPos = input.length; pos < lastPos; ) { for (let i = 0; i < match.length; i++) { match[i].pattern.lastIndex = pos; let found; if ((found = match[i].pattern.exec(input)) !== null) { match[i].action(found); pos = match[i].pattern.lastIndex; break; } } } } let report = (match) => { console.log(JSON.stringify(match)); }; parser("Foo 1 Bar 7 Baz 42", [ { pattern: /^Foo\s+(\d+)/y, action: (match) => report(match) }, { pattern: /^Bar\s+(\d+)/y, action: (match) => report(match) }, { pattern: /^Baz\s+(\d+)/y, action: (match) => report(match) }, { pattern: /^\s*/y, action: (match) => {} } ]);
ECMAScript 5 — syntactic sugar: reduced | traditional
var parser = function (input, match) { for (var i, found, inputTmp = input; inputTmp !== ""; ) { for (i = 0; i < match.length; i++) { if ((found = match[i].pattern.exec(inputTmp)) !== null) { match[i].action(found); inputTmp = inputTmp.substr(found[0].length); break; } } } } var report = function (match) { console.log(JSON.stringify(match)); }; parser("Foo 1 Bar 7 Baz 42", [ { pattern: /^Foo\s+(\d+)/, action: function (match) { report(match); } }, { pattern: /^Bar\s+(\d+)/, action: function (match) { report(match); } }, { pattern: /^Baz\s+(\d+)/, action: function (match) { report(match); } }, { pattern: /^\s*/, action: function (match) {} } ]);
Enhanced Object Properties
Property Shorthand
Shorter syntax for common object property definition idiom.
ECMAScript 6 — syntactic sugar: reduced | traditional
obj = { x, y };
ECMAScript 5 — syntactic sugar: reduced | traditional
obj = { x: x, y: y };
Enhanced Object Properties
Computed Property Names
Support for computed names in object property definitions.
ECMAScript 6 — syntactic sugar: reduced | traditional
let obj = { foo: "bar", [ "baz" + quux() ]: 42 };
ECMAScript 5 — syntactic sugar: reduced | traditional
var obj = { foo: "bar" }; obj[ "baz" + quux() ] = 42;
Enhanced Object Properties
Method Properties
Support for method notation in object property definitions, for both regular functions and generator functions.
ECMAScript 6 — syntactic sugar: reduced | traditional
obj = { foo (a, b) { }, bar (x, y) { }, *quux (x, y) { } };
ECMAScript 5 — syntactic sugar: reduced | traditional
obj = { foo: function (a, b) { }, bar: function (x, y) { }, // quux: no equivalent in ES5 };
Destructuring Assignment
Array Matching
Intuitive and flexible destructuring of Arrays into individual variables during assignment.
ECMAScript 6 — syntactic sugar: reduced | traditional
var list = [ 1, 2, 3 ]; var [ a, , b ] = list; [ b, a ] = [ a, b ];
ECMAScript 5 — syntactic sugar: reduced | traditional
var list = [ 1, 2, 3 ]; var a = list[0], b = list[2]; var tmp = a; a = b; b = tmp;
Destructuring Assignment
Object Matching, Shorthand Notation
Intuitive and flexible destructuring of Objects into individual variables during assignment.
ECMAScript 6 — syntactic sugar: reduced | traditional
var { op, lhs, rhs } = getASTNode();
ECMAScript 5 — syntactic sugar: reduced | traditional
var tmp = getASTNode(); var op = tmp.op; var lhs = tmp.lhs; var rhs = tmp.rhs;
Destructuring Assignment
Object Matching, Deep Matching
Intuitive and flexible destructuring of Objects into individual variables during assignment.
ECMAScript 6 — syntactic sugar: reduced | traditional
var { op: a, lhs: { op: b }, rhs: c } = getASTNode();
ECMAScript 5 — syntactic sugar: reduced | traditional
var tmp = getASTNode(); var a = tmp.op; var b = tmp.lhs.op; var c = tmp.rhs;
Destructuring Assignment
Parameter Context Matching
Intuitive and flexible destructuring of Arrays and Objects into individual parameters during function calls.
ECMAScript 6 — syntactic sugar: reduced | traditional
function f ([ name, val ]) { console.log(name, val); } function g ({ name: n, val: v }) { console.log(n, v); } function h ({ name, val }) { console.log(name, val); } f([ "bar", 42 ]); g({ name: "foo", val: 7 }); h({ name: "bar", val: 42 });
ECMAScript 5 — syntactic sugar: reduced | traditional
function f (arg) { var name = arg[0]; var val = arg[1]; console.log(name, val); }; function g (arg) { var n = arg.name; var v = arg.val; console.log(n, v); }; function h (arg) { var name = arg.name; var val = arg.val; console.log(name, val); }; f([ "bar", 42 ]); g({ name: "foo", val: 7 }); h({ name: "bar", val: 42 });
Destructuring Assignment
Fail-Soft Destructuring
Fail-soft destructuring, optionally with defaults.
ECMAScript 6 — syntactic sugar: reduced | traditional
var list = [ 7, 42 ]; var [ a = 1, b = 2, c = 3, d ] = list; a === 7; b === 42; c === 3; d === undefined;
ECMAScript 5 — syntactic sugar: reduced | traditional
var list = [ 7, 42 ]; var a = typeof list[0] !== "undefined" ? list[0] : 1; var b = typeof list[1] !== "undefined" ? list[1] : 2; var c = typeof list[2] !== "undefined" ? list[2] : 3; var d = typeof list[3] !== "undefined" ? list[3] : undefined; a === 7; b === 42; c === 3; d === undefined;
Modules
Value Export/Import
Support for exporting/importing values from/to modules without global namespace pollution.
ECMAScript 6 — syntactic sugar: reduced | traditional
// lib/math.js export function sum (x, y) { return x + y }; export var pi = 3.141593; // someApp.js import * as math from "lib/math"; console.log("2π = " + math.sum(math.pi, math.pi)); // otherApp.js import { sum, pi } from "lib/math"; console.log("2π = " + sum(pi, pi));
ECMAScript 5 — syntactic sugar: reduced | traditional
// lib/math.js LibMath = {}; LibMath.sum = function (x, y) { return x + y }; LibMath.pi = 3.141593; // someApp.js var math = LibMath; console.log("2π = " + math.sum(math.pi, math.pi)); // otherApp.js var sum = LibMath.sum, pi = LibMath.pi; console.log("2π = " + sum(pi, pi));
Modules
Default & Wildcard
Marking a value as the default exported value and mass-mixin of values.
ECMAScript 6 — syntactic sugar: reduced | traditional
// lib/mathplusplus.js export * from "lib/math"; export var e = 2.71828182846; export default (x) => Math.exp(x); // someApp.js import exp, { pi, e } from "lib/mathplusplus"; console.log("e^{π} = " + exp(pi));
ECMAScript 5 — syntactic sugar: reduced | traditional
// lib/mathplusplus.js LibMathPP = {}; for (symbol in LibMath) if (LibMath.hasOwnProperty(symbol)) LibMathPP[symbol] = LibMath[symbol]; LibMathPP.e = 2.71828182846; LibMathPP.exp = function (x) { return Math.exp(x) }; // someApp.js var exp = LibMathPP.exp, pi = LibMathPP.pi, e = LibMathPP.e; console.log("e^{π} = " + exp(pi));
Classes
Class Definition
More intuitive, OOP-style and boilerplate-free classes.
ECMAScript 6 — syntactic sugar: reduced | traditional
class Shape { constructor (id, x, y) { this.id = id; this.move(x, y); } move (x, y) { this.x = x; this.y = y; } }
ECMAScript 5 — syntactic sugar: reduced | traditional
var Shape = function (id, x, y) { this.id = id; this.move(x, y); }; Shape.prototype.move = function (x, y) { this.x = x; this.y = y; };
Classes
Class Inheritance
More intuitive, OOP-style and boilerplate-free inheritance.
ECMAScript 6 — syntactic sugar: reduced | traditional
class Rectangle extends Shape { constructor (id, x, y, width, height) { super(id, x, y); this.width = width; this.height = height; } } class Circle extends Shape { constructor (id, x, y, radius) { super(id, x, y); this.radius = radius; } }
ECMAScript 5 — syntactic sugar: reduced | traditional
var Rectangle = function (id, x, y, width, height) { Shape.call(this, id, x, y); this.width = width; this.height = height; }; Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; var Circle = function (id, x, y, radius) { Shape.call(this, id, x, y); this.radius = radius; }; Circle.prototype = Object.create(Shape.prototype); Circle.prototype.constructor = Circle;
Classes
Class Inheritance, From Expressions
Support for mixin-style inheritance by extending from expressions yielding function objects. [Notice: the generic aggregation function is usually provided by a library like this one, of course]
ECMAScript 6 — syntactic sugar: reduced | traditional
var aggregation = (baseClass, ...mixins) => { let base = class _Combined extends baseClass { constructor (...args) { super(...args); mixins.forEach((mixin) => { mixin.prototype.initializer.call(this); }); } }; let copyProps = (target, source) => { Object.getOwnPropertyNames(source) .concat(Object.getOwnPropertySymbols(source)) .forEach((prop) => { if (prop.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/)) return Object.defineProperty(target, prop, Object.getOwnPropertyDescriptor(source, prop)) }) } mixins.forEach((mixin) => { copyProps(base.prototype, mixin.prototype); copyProps(base, mixin); }); return base; }; class Colored { initializer () { this._color = "white"; } get color () { return this._color; } set color (v) { this._color = v; } } class ZCoord { initializer () { this._z = 0; } get z () { return this._z; } set z (v) { this._z = v; } } class Shape { constructor (x, y) { this._x = x; this._y = y; } get x () { return this._x; } set x (v) { this._x = v; } get y () { return this._y; } set y (v) { this._y = v; } } class Rectangle extends aggregation(Shape, Colored, ZCoord) {} var rect = new Rectangle(7, 42); rect.z = 1000; rect.color = "red"; console.log(rect.x, rect.y, rect.z, rect.color);
ECMAScript 5 — syntactic sugar: reduced | traditional
var aggregation = function (baseClass, mixins) { var base = function () { baseClass.apply(this, arguments); mixins.forEach(function (mixin) { mixin.prototype.initializer.call(this); }.bind(this)); }; base.prototype = Object.create(baseClass.prototype); base.prototype.constructor = base; var copyProps = function (target, source) { Object.getOwnPropertyNames(source).forEach(function (prop) { if (prop.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/)) return Object.defineProperty(target, prop, Object.getOwnPropertyDescriptor(source, prop)) }) } mixins.forEach(function (mixin) { copyProps(base.prototype, mixin.prototype); copyProps(base, mixin); }); return base; }; var Colored = function () {}; Colored.prototype = { initializer: function () { this._color = "white"; }, getColor: function () { return this._color; }, setColor: function (v) { this._color = v; } }; var ZCoord = function () {}; ZCoord.prototype = { initializer: function () { this._z = 0; }, getZ: function () { return this._z; }, setZ: function (v) { this._z = v; } }; var Shape = function (x, y) { this._x = x; this._y = y; }; Shape.prototype = { getX: function () { return this._x; }, setX: function (v) { this._x = v; }, getY: function () { return this._y; }, setY: function (v) { this._y = v; } } var _Combined = aggregation(Shape, [ Colored, ZCoord ]); var Rectangle = function (x, y) { _Combined.call(this, x, y); }; Rectangle.prototype = Object.create(_Combined.prototype); Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(7, 42); rect.setZ(1000); rect.setColor("red"); console.log(rect.getX(), rect.getY(), rect.getZ(), rect.getColor());
Classes
Base Class Access
Intuitive access to base class constructor and methods.
ECMAScript 6 — syntactic sugar: reduced | traditional
class Shape { toString () { return `Shape(${this.id})` } } class Rectangle extends Shape { constructor (id, x, y, width, height) { super(id, x, y); } toString () { return "Rectangle > " + super.toString(); } } class Circle extends Shape { constructor (id, x, y, radius) { super(id, x, y); } toString () { return "Circle > " + super.toString(); } }
ECMAScript 5 — syntactic sugar: reduced | traditional
var Shape = function (id, x, y) { }; Shape.prototype.toString = function (x, y) { return "Shape(" + this.id + ")" }; var Rectangle = function (id, x, y, width, height) { Shape.call(this, id, x, y); }; Rectangle.prototype.toString = function () { return "Rectangle > " + Shape.prototype.toString.call(this); }; var Circle = function (id, x, y, radius) { Shape.call(this, id, x, y); }; Circle.prototype.toString = function () { return "Circle > " + Shape.prototype.toString.call(this); };
Classes
Static Members
Simple support for static class members.
ECMAScript 6 — syntactic sugar: reduced | traditional
class Rectangle extends Shape { static defaultRectangle () { return new Rectangle("default", 0, 0, 100, 100); } } class Circle extends Shape { static defaultCircle () { return new Circle("default", 0, 0, 100); } } var defRectangle = Rectangle.defaultRectangle(); var defCircle = Circle.defaultCircle();
ECMAScript 5 — syntactic sugar: reduced | traditional
var Rectangle = function (id, x, y, width, height) { }; Rectangle.defaultRectangle = function () { return new Rectangle("default", 0, 0, 100, 100); }; var Circle = function (id, x, y, width, height) { }; Circle.defaultCircle = function () { return new Circle("default", 0, 0, 100); }; var defRectangle = Rectangle.defaultRectangle(); var defCircle = Circle.defaultCircle();
Classes
Getter/Setter
Getter/Setter also directly within classes (and not just within object initializers, as it is possible since ECMAScript 5.1).
ECMAScript 6 — syntactic sugar: reduced | traditional
class Rectangle { constructor (width, height) { this._width = width; this._height = height; } set width (width) { this._width = width; } get width () { return this._width; } set height (height) { this._height = height; } get height () { return this._height; } get area () { return this._width * this._height; } }; var r = new Rectangle(50, 20); r.area === 1000;
ECMAScript 5 — syntactic sugar: reduced | traditional
var Rectangle = function (width, height) { this._width = width; this._height = height; }; Rectangle.prototype = { set width (width) { this._width = width; }, get width () { return this._width; }, set height (height) { this._height = height; }, get height () { return this._height; }, get area () { return this._width * this._height; } }; var r = new Rectangle(50, 20); r.area === 1000;
Symbol Type
Symbol Type
Unique and immutable data type to be used as an identifier for object properties. Symbol can have an optional description, but for debugging purposes only.
ECMAScript 6 — syntactic sugar: reduced | traditional
Symbol("foo") !== Symbol("foo"); const foo = Symbol(); const bar = Symbol(); typeof foo === "symbol"; typeof bar === "symbol"; let obj = {}; obj[foo] = "foo"; obj[bar] = "bar"; JSON.stringify(obj); // {} Object.keys(obj); // [] Object.getOwnPropertyNames(obj); // [] Object.getOwnPropertySymbols(obj); // [ foo, bar ]
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Symbol Type
Global Symbols
Global symbols, indexed through unique keys.
ECMAScript 6 — syntactic sugar: reduced | traditional
Symbol.for("app.foo") === Symbol.for("app.foo") const foo = Symbol.for("app.foo"); const bar = Symbol.for("app.bar"); Symbol.keyFor(foo) === "app.foo"; Symbol.keyFor(bar) === "app.bar"; typeof foo === "symbol"; typeof bar === "symbol"; let obj = {}; obj[foo] = "foo"; obj[bar] = "bar"; JSON.stringify(obj); // {} Object.keys(obj); // [] Object.getOwnPropertyNames(obj); // [] Object.getOwnPropertySymbols(obj); // [ foo, bar ]
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Iterators
Iterator & For-Of Operator
Support "iterable" protocol to allow objects to customize their iteration behaviour. Additionally, support "iterator" protocol to produce sequence of values (either finite or infinite). Finally, provide convenient of operator to iterate over all values of an iterable object.
ECMAScript 6 — syntactic sugar: reduced | traditional
let fibonacci = { [Symbol.iterator]() { let pre = 0, cur = 1; return { next () { [ pre, cur ] = [ cur, pre + cur ]; return { done: false, value: cur }; } }; } } for (let n of fibonacci) { if (n > 1000) break; console.log(n); }
ECMAScript 5 — syntactic sugar: reduced | traditional
var fibonacci = { next: (function () { var pre = 0, cur = 1; return function () { tmp = pre; pre = cur; cur += tmp; return cur; }; })() }; var n; for (;;) { n = fibonacci.next(); if (n > 1000) break; console.log(n); }
Generators
Generator Function, Iterator Protocol
Support for generators, a special case of Iterators containing a generator function, where the control flow can be paused and resumed, in order to produce sequence of values (either finite or infinite).
ECMAScript 6 — syntactic sugar: reduced | traditional
let fibonacci = { *[Symbol.iterator]() { let pre = 0, cur = 1; for (;;) { [ pre, cur ] = [ cur, pre + cur ]; yield cur; } } } for (let n of fibonacci) { if (n > 1000) break; console.log(n); }
ECMAScript 5 — syntactic sugar: reduced | traditional
var fibonacci = { next: (function () { var pre = 0, cur = 1; return function () { tmp = pre; pre = cur; cur += tmp; return cur; }; })() }; var n; for (;;) { n = fibonacci.next(); if (n > 1000) break; console.log(n); }
Generators
Generator Function, Direct Use
Support for generator functions, a special variant of functions where the control flow can be paused and resumed, in order to produce sequence of values (either finite or infinite).
ECMAScript 6 — syntactic sugar: reduced | traditional
function* range (start, end, step) { while (start < end) { yield start; start += step; } } for (let i of range(0, 10, 2)) { console.log(i); // 0, 2, 4, 6, 8 }
ECMAScript 5 — syntactic sugar: reduced | traditional
function range (start, end, step) { var list = []; while (start < end) { list.push(start); start += step; } return list; } var r = range(0, 10, 2); for (var i = 0; i < r.length; i++) { console.log(r[i]); // 0, 2, 4, 6, 8 }
Generators
Generator Matching
Support for generator functions, i.e., functions where the control flow can be paused and resumed, in order to produce and spread sequence of values (either finite or infinite).
ECMAScript 6 — syntactic sugar: reduced | traditional
let fibonacci = function* (numbers) { let pre = 0, cur = 1; while (numbers-- > 0) { [ pre, cur ] = [ cur, pre + cur ]; yield cur; } }; for (let n of fibonacci(1000)) console.log(n); let numbers = [ ...fibonacci(1000) ]; let [ n1, n2, n3, ...others ] = fibonacci(1000);
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Generators
Generator Control-Flow
Support for generators, a special case of Iterators where the control flow can be paused and resumed, in order to support asynchronous programming in the style of "co-routines" in combination with Promises (see below). [Notice: the generic async function usually is provided by a reusable library and given here just for better understanding. See co or Bluebird's coroutine in practice.]
ECMAScript 6 — syntactic sugar: reduced | traditional
// generic asynchronous control-flow driver function async (proc, ...params) { var iterator = proc(...params); return new Promise((resolve, reject) => { let loop = (value) => { let result; try { result = iterator.next(value); } catch (err) { reject(err); } if (result.done) resolve(result.value); else if ( typeof result.value === "object" && typeof result.value.then === "function") result.value.then((value) => { loop(value); }, (err) => { reject(err); }); else loop(result.value); } loop(); }); } // application-specific asynchronous builder function makeAsync (text, after) { return new Promise((resolve, reject) => { setTimeout(() => resolve(text), after); }); } // application-specific asynchronous procedure async(function* (greeting) { let foo = yield makeAsync("foo", 300) let bar = yield makeAsync("bar", 200) let baz = yield makeAsync("baz", 100) return `${greeting} ${foo} ${bar} ${baz}` }, "Hello").then((msg) => { console.log("RESULT:", msg); // "Hello foo bar baz" })
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Generators
Generator Methods
Support for generator methods, i.e., methods in classes and on objects, based on generator functions.
ECMAScript 6 — syntactic sugar: reduced | traditional
class Clz { * bar () { } }; let Obj = { * foo () { } };
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Map/Set & WeakMap/WeakSet
Set Data-Structure
Cleaner data-structure for common algorithms based on sets.
ECMAScript 6 — syntactic sugar: reduced | traditional
let s = new Set(); s.add("hello").add("goodbye").add("hello"); s.size === 2; s.has("hello") === true; for (let key of s.values()) // insertion order console.log(key);
ECMAScript 5 — syntactic sugar: reduced | traditional
var s = {}; s["hello"] = true; s["goodbye"] = true; s["hello"] = true; Object.keys(s).length === 2; s["hello"] === true; for (var key in s) // arbitrary order if (s.hasOwnProperty(key)) console.log(s[key]);
Map/Set & WeakMap/WeakSet
Map Data-Structure
Cleaner data-structure for common algorithms based on maps.
ECMAScript 6 — syntactic sugar: reduced | traditional
let m = new Map(); m.set("hello", 42); m.set(s, 34); m.get(s) === 34; m.size === 2; for (let [ key, val ] of m.entries()) console.log(key + " = " + val);
ECMAScript 5 — syntactic sugar: reduced | traditional
var m = {}; m["hello"] = 42; // no equivalent in ES5 // no equivalent in ES5 Object.keys(m).length === 2; for (key in m) { if (m.hasOwnProperty(key)) { var val = m[key]; console.log(key + " = " + val); } }
Map/Set & WeakMap/WeakSet
Weak-Link Data-Structures
Memory-leak-free Object-key’d side-by-side data-structures.
ECMAScript 6 — syntactic sugar: reduced | traditional
let isMarked = new WeakSet(); let attachedData = new WeakMap(); export class Node { constructor (id) { this.id = id; } mark () { isMarked.add(this); } unmark () { isMarked.delete(this); } marked () { return isMarked.has(this); } set data (data) { attachedData.set(this, data); } get data () { return attachedData.get(this); } } let foo = new Node("foo"); JSON.stringify(foo) === '{"id":"foo"}'; foo.mark(); foo.data = "bar"; foo.data === "bar"; JSON.stringify(foo) === '{"id":"foo"}'; isMarked.has(foo) === true attachedData.has(foo) === true foo = null /* remove only reference to foo */ attachedData.has(foo) === false isMarked.has(foo) === false
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Typed Arrays
Typed Arrays
Support for arbitrary byte-based data structures to implement network protocols, cryptography algorithms, file format manipulations, etc.
ECMAScript 6 — syntactic sugar: reduced | traditional
// ES6 class equivalent to the following C structure: // struct Example { unsigned long id; char username[16]; float amountDue; }; class Example { constructor (buffer = new ArrayBuffer(24)) { this.buffer = buffer; } set buffer (buffer) { this._buffer = buffer; this._id = new Uint32Array (this._buffer, 0, 1); this._username = new Uint8Array (this._buffer, 4, 16); this._amountDue = new Float32Array(this._buffer, 20, 1); } get buffer () { return this._buffer; } set id (v) { this._id[0] = v; } get id () { return this._id[0]; } set username (v) { this._username[0] = v; } get username () { return this._username[0]; } set amountDue (v) { this._amountDue[0] = v; } get amountDue () { return this._amountDue[0]; } } let example = new Example() example.id = 7 example.username = "John Doe" example.amountDue = 42.0
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5 // (only an equivalent in HTML5)
New Built-In Methods
Object Property Assignment
New function for assigning enumerable properties of one or more source objects onto a destination object.
ECMAScript 6 — syntactic sugar: reduced | traditional
var dst = { quux: 0 }; var src1 = { foo: 1, bar: 2 }; var src2 = { foo: 3, baz: 4 }; Object.assign(dst, src1, src2); dst.quux === 0; dst.foo === 3; dst.bar === 2; dst.baz === 4;
ECMAScript 5 — syntactic sugar: reduced | traditional
var dst = { quux: 0 }; var src1 = { foo: 1, bar: 2 }; var src2 = { foo: 3, baz: 4 }; Object.keys(src1).forEach(function(k) { dst[k] = src1[k]; }); Object.keys(src2).forEach(function(k) { dst[k] = src2[k]; }); dst.quux === 0; dst.foo === 3; dst.bar === 2; dst.baz === 4;
New Built-In Methods
Array Element Finding
New function for finding an element in an array.
ECMAScript 6 — syntactic sugar: reduced | traditional
[ 1, 3, 4, 2 ].find(x => x > 3); // 4
ECMAScript 5 — syntactic sugar: reduced | traditional
[ 1, 3, 4, 2 ].filter(function (x) { return x > 3; })[0]; // 4
New Built-In Methods
String Repeating
New string repeating functionality.
ECMAScript 6 — syntactic sugar: reduced | traditional
" ".repeat(4 * depth); "foo".repeat(3);
ECMAScript 5 — syntactic sugar: reduced | traditional
Array((4 * depth) + 1).join(" "); Array(3 + 1).join("foo");
New Built-In Methods
String Searching
New specific string functions to search for a sub-string.
ECMAScript 6 — syntactic sugar: reduced | traditional
"hello".startsWith("ello", 1); // true "hello".endsWith("hell", 4); // true "hello".includes("ell"); // true "hello".includes("ell", 1); // true "hello".includes("ell", 2); // false
ECMAScript 5 — syntactic sugar: reduced | traditional
"hello".indexOf("ello") === 1; // true "hello".indexOf("hell") === (4 - "hell".length); // true "hello".indexOf("ell") !== -1; // true "hello".indexOf("ell", 1) !== -1; // true "hello".indexOf("ell", 2) !== -1; // false
New Built-In Methods
Number Type Checking
New functions for checking for non-numbers and finite numbers.
ECMAScript 6 — syntactic sugar: reduced | traditional
Number.isNaN(42) === false; Number.isNaN(NaN) === true; Number.isFinite(Infinity) === false; Number.isFinite(-Infinity) === false; Number.isFinite(NaN) === false; Number.isFinite(123) === true;
ECMAScript 5 — syntactic sugar: reduced | traditional
var isNaN = function (n) { return n !== n; }; var isFinite = function (v) { return (typeof v === "number" && !isNaN(v) && v !== Infinity && v !== -Infinity); }; isNaN(42) === false; isNaN(NaN) === true; isFinite(Infinity) === false; isFinite(-Infinity) === false; isFinite(NaN) === false; isFinite(123) === true;
New Built-In Methods
Number Safety Checking
Checking whether an integer number is in the safe range, i.e., it is correctly represented by JavaScript (where all numbers, including integer numbers, are technically floating point number).
ECMAScript 6 — syntactic sugar: reduced | traditional
Number.isSafeInteger(42) === true; Number.isSafeInteger(9007199254740992) === false;
ECMAScript 5 — syntactic sugar: reduced | traditional
function isSafeInteger (n) { return ( typeof n === 'number' && Math.round(n) === n && -(Math.pow(2, 53) - 1) <= n && n <= (Math.pow(2, 53) - 1) ); } isSafeInteger(42) === true; isSafeInteger(9007199254740992) === false;
New Built-In Methods
Number Comparison
Availability of a standard Epsilon value for more precise comparison of floating point numbers.
ECMAScript 6 — syntactic sugar: reduced | traditional
console.log(0.1 + 0.2 === 0.3); // false console.log(Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON); // true
ECMAScript 5 — syntactic sugar: reduced | traditional
console.log(0.1 + 0.2 === 0.3); // false console.log(Math.abs((0.1 + 0.2) - 0.3) < 2.220446049250313e-16); // true
New Built-In Methods
Number Truncation
Truncate a floating point number to its integral part, completely dropping the fractional part.
ECMAScript 6 — syntactic sugar: reduced | traditional
console.log(Math.trunc(42.7)) // 42 console.log(Math.trunc( 0.1)) // 0 console.log(Math.trunc(-0.1)) // -0
ECMAScript 5 — syntactic sugar: reduced | traditional
function mathTrunc (x) { return (x < 0 ? Math.ceil(x) : Math.floor(x)); } console.log(mathTrunc(42.7)) // 42 console.log(mathTrunc( 0.1)) // 0 console.log(mathTrunc(-0.1)) // -0
New Built-In Methods
Number Sign Determination
Determine the sign of a number, including special cases of signed zero and non-number.
ECMAScript 6 — syntactic sugar: reduced | traditional
console.log(Math.sign(7)) // 1 console.log(Math.sign(0)) // 0 console.log(Math.sign(-0)) // -0 console.log(Math.sign(-7)) // -1 console.log(Math.sign(NaN)) // NaN
ECMAScript 5 — syntactic sugar: reduced | traditional
function mathSign (x) { return ((x === 0 || isNaN(x)) ? x : (x > 0 ? 1 : -1)); } console.log(mathSign(7)) // 1 console.log(mathSign(0)) // 0 console.log(mathSign(-0)) // -0 console.log(mathSign(-7)) // -1 console.log(mathSign(NaN)) // NaN
Promises
Promise Usage
First class representation of a value that may be made asynchronously and be available in the future.
ECMAScript 6 — syntactic sugar: reduced | traditional
function msgAfterTimeout (msg, who, timeout) { return new Promise((resolve, reject) => { setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout); }); } msgAfterTimeout("", "Foo", 100).then((msg) => msgAfterTimeout(msg, "Bar", 200) ).then((msg) => { console.log(`done after 300ms:${msg}`); });
ECMAScript 5 — syntactic sugar: reduced | traditional
function msgAfterTimeout (msg, who, timeout, onDone) { setTimeout(function () { onDone(msg + " Hello " + who + "!"); }, timeout); } msgAfterTimeout("", "Foo", 100, function (msg) { msgAfterTimeout(msg, "Bar", 200, function (msg) { console.log("done after 300ms:" + msg); }); });
Promises
Promise Combination
Combine one or more promises into new promises without having to take care of ordering of the underlying asynchronous operations yourself.
ECMAScript 6 — syntactic sugar: reduced | traditional
function fetchAsync (url, timeout, onData, onError) { } let fetchPromised = (url, timeout) => { return new Promise((resolve, reject) => { fetchAsync(url, timeout, resolve, reject); }); } Promise.all([ fetchPromised("http://backend/foo.txt", 500), fetchPromised("http://backend/bar.txt", 500), fetchPromised("http://backend/baz.txt", 500) ]).then((data) => { let [ foo, bar, baz ] = data; console.log(`success: foo=${foo} bar=${bar} baz=${baz}`); }, (err) => { console.log(`error: ${err}`); });
ECMAScript 5 — syntactic sugar: reduced | traditional
function fetchAsync (url, timeout, onData, onError) { } function fetchAll (request, onData, onError) { var result = [], results = 0; for (var i = 0; i < request.length; i++) { result[i] = null; (function (i) { fetchAsync(request[i].url, request[i].timeout, function (data) { result[i] = data; if (++results === request.length) onData(result); }, onError); })(i); } } fetchAll([ { url: "http://backend/foo.txt", timeout: 500 }, { url: "http://backend/bar.txt", timeout: 500 }, { url: "http://backend/baz.txt", timeout: 500 } ], function (data) { var foo = data[0], bar = data[1], baz = data[2]; console.log("success: foo=" + foo + " bar=" + bar + " baz=" + baz); }, function (err) { console.log("error: " + err); });
Meta-Programming
Proxying
Hooking into runtime-level object meta-operations.
ECMAScript 6 — syntactic sugar: reduced | traditional
let target = { foo: "Welcome, foo" }; let proxy = new Proxy(target, { get (receiver, name) { return name in receiver ? receiver[name] : `Hello, ${name}`; } }); proxy.foo === "Welcome, foo"; proxy.world === "Hello, world";
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Meta-Programming
Reflection
Make calls corresponding to the object meta-operations.
ECMAScript 6 — syntactic sugar: reduced | traditional
let obj = { a: 1 }; Object.defineProperty(obj, "b", { value: 2 }); obj[Symbol("c")] = 3; Reflect.ownKeys(obj); // [ "a", "b", Symbol(c) ]
ECMAScript 5 — syntactic sugar: reduced | traditional
var obj = { a: 1 }; Object.defineProperty(obj, "b", { value: 2 }); // no equivalent in ES5 Object.getOwnPropertyNames(obj); // [ "a", "b" ]
Internationalization & Localization
Collation
Sorting a set of strings and searching within a set of strings. Collation is parameterized by locale and aware of Unicode.
ECMAScript 6 — syntactic sugar: reduced | traditional
// in German, "ä" sorts with "a" // in Swedish, "ä" sorts after "z" var list = [ "ä", "a", "z" ]; var l10nDE = new Intl.Collator("de"); var l10nSV = new Intl.Collator("sv"); l10nDE.compare("ä", "z") === -1; l10nSV.compare("ä", "z") === +1; console.log(list.sort(l10nDE.compare)); // [ "a", "ä", "z" ] console.log(list.sort(l10nSV.compare)); // [ "a", "z", "ä" ]
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Internationalization & Localization
Number Formatting
Format numbers with digit grouping and localized separators.
ECMAScript 6 — syntactic sugar: reduced | traditional
var l10nEN = new Intl.NumberFormat("en-US"); var l10nDE = new Intl.NumberFormat("de-DE"); l10nEN.format(1234567.89) === "1,234,567.89"; l10nDE.format(1234567.89) === "1.234.567,89";
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Internationalization & Localization
Currency Formatting
Format numbers with digit grouping, localized separators and attached currency symbol.
ECMAScript 6 — syntactic sugar: reduced | traditional
var l10nUSD = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }); var l10nGBP = new Intl.NumberFormat("en-GB", { style: "currency", currency: "GBP" }); var l10nEUR = new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" }); l10nUSD.format(100200300.40) === "$100,200,300.40"; l10nGBP.format(100200300.40) === "£100,200,300.40"; l10nEUR.format(100200300.40) === "100.200.300,40 €";
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Internationalization & Localization
Date/Time Formatting
Format date/time with localized ordering and separators.
ECMAScript 6 — syntactic sugar: reduced | traditional
var l10nEN = new Intl.DateTimeFormat("en-US"); var l10nDE = new Intl.DateTimeFormat("de-DE"); l10nEN.format(new Date("2015-01-02")) === "1/2/2015"; l10nDE.format(new Date("2015-01-02")) === "2.1.2015";
ECMAScript 5 — syntactic sugar: reduced | traditional
// no equivalent in ES5
Copyright © 2015-2016 Ralf S. Engelschall   @engelschall
Fully generated from a single source
Licensed under MIT License.