ecmascript 6
DESCRIPTION
ECMAScript 6. Luke Hoban git.io/es6features. ECMAScript History. ECMAScript 6. ES6 More significant changes than ES5 Much more new syntax Very , very high back compat Spec drafts Spec drafts ~ Monthly updates Currently at Rev 25 Spec ‘feature complete’ ‘Final’ spec target 7/2014 - PowerPoint PPT PresentationTRANSCRIPT
ECMAScript 6Luke Hobangit.io/es6features
ECMAScript History
1997 2015
1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
2014
1997
ECMAScript 11998
ECMAScript 21999
ECMAScript 3
2009
ECMAScript 52014
ECMAScript 6?2005 - 2007
ECMAScript 4 - Abandoned
ECMAScript 6
• ES6• More significant changes than ES5• Much more new syntax• Very, very high back compat
• Spec drafts• Spec drafts• ~ Monthly updates• Currently at Rev 25• Spec ‘feature complete’• ‘Final’ spec target 7/2014• ECMA ratification target 12/2014• Implementation progress: http://kangax.github.io/es5-compat-table/es6/
ES6 for Developers(the sugar)
arrows
• Function shorthand with =>• Syntactically similar to C#, Java 8,
CoffeeScript• Support for expression and
statement bodies
• Goal: Shorthand for common usage of functions as callbacks
// Expression bodiesvar odds = evens.map(v => v + 1); var nums = evens.map((v, i) => v + i);
// Statement bodiesnums.forEach(v => { if (v % 5 === 0) fives.push(v); });
// Lexical thisvar bob = { _name: "Bob", _friends: [], printFriends() { this._friends.forEach(f => console.log(this._name + " knows " + f)); }}
classes• Simple classes as sugar• Compiles to prototype-based OO
pattern• Formalizes common JS OO pattern
into syntax
• Goal: Declarative classes covering common case
class SkinnedMesh extends THREE.Mesh { constructor(geometry, materials) { super(geometry, materials); this.idMatrix = SkinnedMesh.defaultMatrix(); this.bones = []; this.boneMatrices = []; //... } update(camera) { //... super.update(); } static defaultMatrix() { return new THREE.Matrix4(); }}
enhanced object literals
• Richer object literals• Covers common scenarios like:
• setting prototype at construction• defining methods• accessing super from method
var obj = { // __proto__ __proto__: theProtoObj, // Shorthand for ‘handler: handler’ handler, // Methods toString() { // Super calls return "d " + super.toString() }};
template strings // Basic literal string creation
`In JavaScript '\n' is a line-feed.`
// Multiline strings`In JavaScript this is not legal.`
// Construct a DOM query var name = "Bob", time = "today";`Hello ${name}, how are you ${time}?`
// Construct an HTTP request// Prefix is used to interpret the // replacements and constructionGET`http://foo.org/bar?a=${a}&b=${b} Content-Type: application/json X-Credentials: ${credentials} { "foo": ${foo}, "bar": ${bar}}`(myOnReadyStateChangeHandler);
• Syntactic sugar for string construction• Similar to string interpolation in Perl,
Python
• Goal: Make it easier to construct strings with less risk of injection attacks
destructuring
• Binding via pattern matching• Support for matching arrays,
objects
// list matchingvar [a, , b] = [1,2,3];
// object matchingvar { op: a, lhs: { op: b }, rhs: c } = getASTNode()
// Can be used in parameter positionfunction g({name: x}) { console.log(x);}g({name: 5})
default + rest + spread
• Callee-evaluated default parameter values
• Turn an array into consecutive arguments in a function call
• Bind trailing parameters to an array
• Goal: Write less code, replace ‘arguments’
function f(x, y=12) { // y is 12 if not passed return x + y;}f(3)
function f(x, ...y) { // y is an Array return x * y.length;}f(3, "hello", true)
function f(x, y, z) { return x + y + z;}// Pass each elem of array as argumentf(...[1,2,3])
11
ES6 for Library Builders
(the capabilities)
map + set + weakmap
• Efficient Map and Set data structures
• WeakMap provides leak-free object-key’d side tables
• Goal: Enable libraries to provide new experiences
// Setsvar s = new Set();s.add("hello").add("goodbye").add("hello");s.size === 2;s.has("hello") === true;
// Mapsvar m = new Map();m.set("hello", 42);m.set(s, 34);m.get(s) == 34;
// Weak Mapsvar wm = new WeakMap();m.set(s, { extra: 42 });m.size === undefined
proxies• Enable creation of objects with full
range of behaviors available to host object
• Support interception, object virtualization, logging/profiling, etc.
• Continue the direction set by Object.* in ES5
• Goal: Enable libraries to provide new experiences
• Semantics: Proxy semantics restricted to “proxy” objects, not general interception
var handler = { getOwnPropertyDescriptor: ..., getOwnPropertyNames: ..., defineProperty: ..., deleteProperty: ..., get: ..., set: ..., // …}
var obj = {x: 1};
// Create a proxy wrapping an objectvar proxy = Proxy(obj, handler);
// Invokes trap on handlerproxy.x = 3;
symbols• Allow properties to be keyed by either string
(as in ES5) or Symbols• Symbols are a new primitive type• Optional ‘name’ parameter used in
debugging
• Goal: Enable granular access control to per-instance properties
• Note: Originally two kinds ‘private’ and ‘unique’. • Private are not exposed to reflection APIs. These
were postponed out of ES6 due to complexities rationalizing with proxies and other reflection mechanisms.
• Unique are exposed to reflection like normal properties. There continues to be discussion about whether these are worth it given the limitied benefit over “_key”.
(function() { // module scoped symbol var key = Symbol("key");
function MyClass(privateData) { this[key] = privateData; }
MyClass.prototype = { doStuff: function() { ... this[key] ... } };
})();
var c = new MyClass("hello") c["key"] === undefined
subclassable builtins• Construction for Ctor now uses two-
phases (both virtually dispatched):• Call Ctor[@@create] to allocate the object,
installing any special behavior• Invoke constructor on new instance to
initialize• The known @@create symbol is
available via Symbol.create• Built-ins now expose their @@create
explicitly
• Goal: Enable subclassing built-ins like Array, Date and DOM.
• Note: Web components can leverage DOM subclassability.
// Psuedo-code of Arrayclass Array { constructor(...args) { /* ... */ } static [Symbol.create]() { // Install special [[DefineOwnProperty]] // to magically update 'length' }}
// User code of Array subclassclass MyArray extends Array { constructor(...args) { super(...args); }}
// Two-phase 'new':// 1) Call @@create to allocate object// 2) Invoke constructor on new instancevar arr = new MyArray();arr[1] = 12;arr.length == 2
tail calls
• Calls in tail-position are guaranteed to not grow the stack unboundedly.
• Makes recursive algorithms safe in the face of unbounded inputs.
• Provides a better compilation target for languages that depend on tail call optimization
function factorial(n, acc = 1) { 'use strict'; if (n <= 1) return acc; return factorial(n - 1, n * acc);}
// Stack overflow in most implementations today,// but safe on arbitrary inputs in eS6factorial(100000)
ES6 for Scalable Applications(the meat)
let + const• Block-scoped binding
• ‘let’ is the new ‘var’• ‘const’ is single-assignment
• Goal: Address existing confusion around scoping, align with expectation from other C-style languages
• Goal: ‘const’ offers optimization opportunities
• Semantics: No use before definition
function f() { { let x; { // okay, block scoped name const x = "sneaky"; // error, const x = "foo"; } // error, already declared in block let x = "inner"; }}
iterators + for..of• Iterator objects enable custom iteration like
CLR IEnumerable or Java Iteratable• Generalize for-in to custom iterator-based
iteration with for-of• Don’t require realizing an array
• Goal: Open up new kinds of iteration, including databases (LINQ)
interface IteratorResult { done: boolean; value: any;}interface Iterator { next(): IteratorResult; }interface Iterable { [Symbol.iterator](): Iterator }
var fibonacci = { [Symbol.iterator]() { var pre = 0, cur = 1; return { next() { var temp = pre; pre = cur; cur += temp; return { done: false, value: cur } } } }}
for (var n of fibonacci) { // truncate the sequence at 1000 if (n > 1000) break; print(n);}
generators• Simplify iterator-authoring using ‘function*’ and
‘yield’• A function declared as function* returns a
Generator instance• Generators are subtypes of Iterators
• Notably enabling values to flow back into the generator• So ‘yield’ is an expression form which returns a value (or
throws)
interface Generator extends Iterator { next(value?: any): IteratorResult; throw(exception: any);}
• Goal: Open up new kinds of iteration, including databases (LINQ)
• Note: Enables ‘await’-like async programming
var fibonacci = { [Symbol.iterator]: function*() { var pre = 0, cur = 1; for (;;) { var temp = pre; pre = cur; cur += temp; yield cur; } }}
for (var n of fibonacci) { // truncate the sequence at 1000 if (n > 1000) break; print(n);}
comprehensions• Sugar over simple iterator composition• Option to realize results as array or generator
• Goal: Compact queries over in memory data
// Array comprehensionsvar results = [ for(c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }]
// Generator comprehensionsvar results = { for(c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }}
unicode• Non-breaking additions to support
full Unicode• New RegExp mode to handle code
points• Several new libraries to support
processing strings as 21bit code points
• Goal: Support building global apps in JavaScript• see also TC39 i18n library working
group
// same as ES5.1"𠮷 ".length == 2
// new RegExp behaviour, opt-in ‘u’"𠮷 ".match(/./u)[0].length == 2
// new form"\u{20BB7}"=="𠮷 "=="\uD842\uDFB7"
// new String ops"𠮷 ".codePointAt(0) == 0x20BB7
// for-of iterates code pointsfor(var c of "𠮷 ") { console.log(c); }
modules• Language-level support for
modules• Codify patterns from popular
JavaScript module loaders (AMD, CommonJS)
• Host-defined default loader• Implicitly async model – no code
executes until requested modules are available and processed
• Goal: Enable component definition and usage
// lib/math.jsexport function sum(x, y) { return x + y;}export var pi = 3.141593;
// app.jsmodule math from "lib/math”;alert("2π = " + math.sum(math.pi, math.pi));
// otherApp.jsimport {sum, pi} from "lib/math”;alert("2π = " + sum(pi, pi));
modules (2)• Default export
• A single anonymous exported value
• Imported with ‘import foo from …”• Imagine that jQuery might be a
default export• Library author must decide –
default export or multi-export?• ‘export *’ to auto-re-export• No ‘import *’ yet
• This can be brittle with versioning
// lib/mathplusplus.jsexport * from "lib/math”;export var e = 2.71828182846;export default function(x) { return Math.exp(x);}
// app.jsmodule math from "lib/mathplusplus”;import exp from "lib/mathplusplus”;alert("2π = " + exp(math.pi, math.e));
module loaders
• Dynamic loading• State isolation• Global namespace isolation• Compilation hooks• Nested virtualization
• Goal: Support code loading natively in the JavaScript engine
// Dynamic loading – ‘System’ is default loaderSystem.import('lib/math').then(function(m) { alert("2π = " + m.sum(m.pi, m.pi)); });
// Create execution sandboxes – new Loadersvar loader = new Loader({ global: fixup(window) // replace ‘console.log’});loader.eval("console.log('hello world!';)")
// Directly manipulate module cacheSystem.get('jquery')System.set('jquery', Module({$: $}))
The rest…
• New Math, Number, String and Object APIs
• Reflect API• RegExp extensions (/y, /u)
ES7?
• Object.observe• async/await• Weak References• Parallel JavaScript• Decorators• Value objects (int64 and bignum)
git.io/[email protected]
Q&A