ECMAScript is the standardized language
Best known implementation is JavaScript
ECMAScript 6 is a superset of current version
other implementations include JScript, ActionScriptJavaScript
This is how many devs from other languages see JS Perhaps fairly to some extentDespite its quirks...
JavaScript is the most widely deployed programming language in the world
Browser : Server : Database : Automation
It's king of the web, no other language even comes close
Any application that can be written in JavaScript, will eventually be written in JavaScript.
~Atwood's Law
Current version is ECMAScript 5.1 (2011)
Next version is officially ECMAScript 2015
ECMAScript 6 (ES6) mindshare tough to penetrate
ES 5.1 is a maintenance release atop 5.0 (2009) Year in name intended to reflect faster release cadenceECMAScript 6 is complete
Spec is finalized
Publication in June 2015
Browsers continually implementing features
Fully compliant browser by end of 2015?
Transpile: ES6 -> ES5
ES6 Shims
Sourcemaps
Module System
Transpilers: Babel, Traceur, TypeScript Shims: es6-shim Sourcemaps: transpiler options Module system: Browserify, webpack, JSPMES < 6 has lexical scoping only
ES6 introduces let and const for block scoping
Block scoped function declarations
ES <= 5.1 has lexical scoping only.let foo = 'bar'; console.log(foo); // barLet is not hoisted
console.log(foo); // Reference Error let foo = 'bar';Let is not hoisted, so declaration must come before usage
var foo = 'bar'; { let foo = 'baz'; console.log(foo); // baz } console.log(foo); // barTrue block scoping here
const foo = 'bar'; console.log(foo) // bar foo = 'baz' // TypeErrorEmulates immutability by disallowing reassignment
const locks assignment only, not value
const foo = [1, 2, 3]; foo = [4, 5]; // TypeError foo.concat([4, 5]); console.log(foo); // [1, 2, 3, 4, 5]Const is not immutable, the value of the entity can be changed Only prevents reassignment, values are mutable
{ foo(); // ok function foo() {} } foo(); // ReferenceErrorBlock scoped functions
Terse function syntax
Lexical "this" binding
Inspired by C# and CoffeeScript
Arrow function intro// ES5 function square(x) { return x * x; } // ES6 let square = x => x * x;
// ES5 [1, 2, 3].map(function (x) { return x * x; } // ES6 [1, 2, 3].map(x => x * x);
arg => expr arg => { stmt1; stmt2; ... } (arg1, arg2, ...) => expr (arg1, arg2, ...) => { stmt1; stmt2; ... }
// ES5 function Widget() { var that = this; var b = document.querySelector('#btn1'); b.addEventListener('click', function() { that.someMethod(); }); } // ES6 function Widget() { let b = document.querySelector('#btn1'); b.addEventListener('click', () => { this.someMethod(); }); }.forEach() takes an optional 2nd 'this' param, example is to make a point only
() => {} can be used almost everywhere function() is used, but...
Best for short, simple functions, where terseness shines
Always function expressions, can't be hoisted
Deprecated "arguments" object is not available
Not a drop-in replacement for function.ES6 introduces object literal enhancements
Property shorthand
Compact method syntax
Computed properties
var a = 1, b = 2; // ES5 var foo = { a: a, b: b }; // ES6 let foo = { a, b };
// ES5 var foo = { bar: function (x) { return x; } } // ES6 let foo = { bar(x) { return x; } }
let foo = { ['foo' + 'Bar']: function (x) { return x + x; } } foo.fooBar(3); // 6Main value is Symbols No name clashes Private methods/properties
Classes are the most divisive ES6 addition
Syntactic sugaring of constructor functions and prototypes
// ES5 function Foo(bar) { this.bar = bar; } Foo.prototype.baz = function() { } var foo = new Foo('bar');
// ES6 class Foo { constructor(bar) { this.bar = bar; } baz() { } } let foo = new Foo('bar');
class Foo { constructor(bar) { this.bar = bar; } static baz() { } } let foo = new Foo('bar'); Foo.baz() // ok foo.baz(); // undefined
class Foo { constructor(bar) { this.bar = bar; } } class FooBar extends Foo { constructor(bar) { super(bar); } } let fooBar = new FooBar('baz'); console.log(fooBar.bar); // baz fooBar instanceof Foo // trueMention getters / setters, avaiable on objects in ES5
class Foo extends Array{ first() { return this[0]; } last() { return this[this.length - 1]; } } let foo = new Foo(1, 2, 3); foo.first(); // 1 foo.last(); // 3 foo instanceof Array // true
Friendlier to class-based OO developers
Standardized vs. various lib/framework implementations
Tooling (IDEs, transpilers, type checkers, etc.)
Subclassing built-in objects
Syntax very different from semantics
Constructor-based inheritance
Encourages inheritance over composition
super()
You can set up prototype chains without constructors Constructors tie object creation with initialization// ES5 function foo (bar) { var bar = bar || 'baz'; } // ES6 function foo(bar='baz') { }
function f({foo='fee', bar='baz'}={}) { console.log(foo + ', ' + bar); } f({foo: 'fum', bar: 'bim'}); // fum, bim f({foo: 'fum'}); // fum, baz f(); // fee, baz
function f(arg, cb=Function.prototype) { // do something... cb(arg); } let myCb = x => { console.log(x); }; f('foo', myCb); // foo f('foo'); // no-op
Dual personality:
Gathering values ("rest" parameters)
Spreading values ("spread" operator)
// ES5 function foo () { var args = [].slice.call(arguments); console.log(args.shift()); ok } // ES6 function foo(...rest) { console.log(rest.shift()); ok }
function f(arg, ...rest) {} // ok function f(arg1, arg2, ...rest) {} // ok function f(...rest, arg) {} // SyntaxError
let arr1 = [4, 5]; let arr2 = [1, 2, 3, ...arr1, 6]; console.log(arr2); // [1, 2, 3, 4, 5, 6]
function foo (a, b, c, d, e, f) {} let args = [3, 4]; foo(1, 2, ...args, 5, 6);
// 'apply' for constructors let dateParts = [1995, 11, 1]; new Date(...dateParts); // Fri Dec 01 1995
Concise syntax for extracting data from arrays and objects
// ES5 var arr = [1, 2, 3]; var a = arr[0]; var b = arr[1]; var c = arr[2]; // ES6 let [a, b, c] = [1, 2, 3];
let [a, , , [, e]] = [1, 2, 3, [4, 5]]; console.log(a); // 1 console.log(e); // 5
let a = 1, b = 2; [b, a] = [a, b]; console.log(a); // 2 console.log(b); // 1
let [a, b, ...rest] = [1, 2, 3, 4, 5]; console.log(rest.length); // 3 console.log(rest.shift()); // 3 console.log(rest.shift()); // 4 console.log(rest.shift()); // 5
// ES5 var obj = {a: 1, b: 2}; var a = obj.a; var b = obj.b; // ES6 let {a, b} = {a: 1, b: 2};
let {b: {c, d}} = {a: 1, b: {c: 3, d: 4}}; console.log(c); // 3 console.log(d); // 4
let {a: one, b: two} = {a: 1, b: 2}; console.log(one); // 1 console.log(one); // 2Note source: target syntax
String literals allowing embedded expressions
Supports multi-line strings
Add an example of expression interpolation?// ES5 var name = 'Dave'; var greeting = 'Good morning ' + name; // ES6 let name = 'Dave'; let greeting = `Good morning ${name}`;
// ES5 var aString = 'string text line\n' + 'string text line2\n'; // ES6 let aString = `string text line 1 string text line2`;Add an example of expression interpolation?
Modify output of template strings with a function
Function takes an array of string literals, and ...rest values
function upper(strs, ...vals) { return strs.reduce(function (p, c, i) { if (i > 0) { p += vals[i-1].toUpperCase(); } return p + c; }, ''); } let him = 'Dave', me = 'Hal'; let str = upper`Hello ${him}, it's ${me}`; console.log(str); // Hello DAVE, it's HALString.raw
function raw(strs, ...vals) { console.log(strs); console.log(strs.raw); } raw`Foo\nBar`; // ["Foo↵Bar"] // ["Foo\nBar"] console.log(String.raw('Foo\nBar')); // "Foo\nBar"String.raw
Standardized module syntax, sync and async
Replaces CommonJS, AMD, and UMD
CommonJS-like syntax
How many are using a module system today? Which one?// foo.js export bar = (baz) => baz; export baz = (fum) => fum;
// foo.js let bar = (baz) => baz; let baz = (fum) => fum; export default { bar, baz };
// default exports import foo from './foo'; // named exports import { bar, baz } from './foo'; // default + named exports import foo, { bar, baz } from './foo'; // named exports as object import * as foo from './foo'; // load module but don't import import './foo';
Define, load, configure modules programmatically
Each host environment implements 'System'
// load one module (with ES6 promises) System.import('myModule') .then(myModule => { // use myModule }); // load multiple modules Promise.all( ['m1', 'm2', 'm3']. map(m => System.import(m))) .then(([m1, m2, m3]) => { // use m1, m2, m3 });
Until loader API is implemented, build layer transpile/transform: