ECMAScript
An introduction
http://bit.ly/es6-z
Paul Verbeek
@_paulverbeek
http://nlhtml5.org
https://www.polymer-project.org/summit
ECMAScript
http://bit.ly/es6-z
ECMAScript 6
ECMAScript 2015
ECMAScript Harmony
ECMAScript?
ECMA-262
ECMA-402
Dart Programming Language
ECMA-222
Adaptive Lossless Data Compression Algorithm
ECMA-74
Measurement of Airborne Noise Emitted by Information Technology and Telecommunications Equipment
ECMA-262
ECMAScript® Language Specification
ActionScript
Adobe ExtendScript
JScript
JScript.NET
JavaScript
ECMA-262 6th edition
The ECMAScript® 2015 Language Specification
ES6
ECMAScript 5.1
-
strict mode ("use strict")
-
JSON
-
String.trim()
-
getters & setters
- Function.prototype.bind()
-
New Object methods (e.g. Object.create())
-
New Array methods (e.g. Array.map())
-
Date.now()
ECMAScript 5.1
ECMAScript 6
ECMAScript 6
-
Arrow functions
-
Binary and Octal Literals
-
Block-scoped variables
-
Classes
-
Comprehension
-
Default + rest + spread parameters
-
Destructuring
-
Iterators
-
Generators
-
Map + Set + WeakMap + WeakSet
ECMAScript 6
-
Math + Number + String + Object APIs
-
Modules
-
Promises
-
Proxies
-
Reflect API
-
Subclassable Built-ins
-
Symbols
-
Tail Calls
-
Template strings
-
Unicode
ECMAScript 6
-
Arrow functions
-
Block-scoped variables
-
Classes
-
Default, rest & spread parameters
-
Destructuring
-
Modules
-
Template strings
Block-scoped variables
function logDan() {
if (true) {
var name = 'Dan Rubin';
}
console.log(name);
}
logDan();
Function-scoped variables
function logDan() {
if (true) {
var name = 'Dan Rubin';
}
console.log(name); // Dan Rubin
}
logDan();
function logDan() {
var name = undefined;
if (true) {
name = 'Dan Rubin';
}
console.log(name);
}
logDan();
Block-scoped variables
function logDan() {
if (true) {
let name = 'Dan Rubin';
}
console.log(name); // name is not defined
}
logDan();
function logTheDans() {
let dans = ['Dan Rubin',
'Dan Aykroyd',
'Dan Stevens'],
for (let i = 0; i < dans.length; i++) {
console.log(dans[i]);
}
console.log(i); // i is not defined
}
logTheDans();
var globalVar = 'global variable';
let globalLet = 'also global';
function f() {
var functionVar = 'function-scoped';
let functionLet = 'this one too';
}
f();
function logDan() {
let name = 'Dan Rubin';
let name = 'Dan Aykroyd';
// Identifier 'name' has already been declared
console.log(name);
}
logDan();
Block-scoped variables
function logBestDan() {
const DAN = 'Dan Rubin';
DAN = 'Dan Stevens';
// 'DAN' is read-only
console.log(DAN);
}
logBestDan();
Block-scoped variables
function logBestDan() {
const DAN = {
firstName: 'Dan',
lastName: 'Aykroyd'
};
DAN.lastName = 'Rubin';
console.log(DAN.lastName); // Rubin
}
logBestDan();
Block-scoped variables
function logBestDan() {
const DAN = {
firstName: 'Dan',
lastName: 'Aykroyd'
};
DAN = {};
// 'DAN' is read-only
console.log(DAN);
}
logBestDan();
Destructuring
// Single values
var name = {};
name.first = 'Dan';
name.last = 'Rubin';
// Single values
var first = name.first;
var last = name.last;
// Single values
var name = {};
name.first = 'Dan';
name.last = 'Rubin';
// Multiple values
var name = {
first: 'Dan',
last: 'Rubin'
};
Constructing
Extracting
vs.
// Single values
var first = name.first;
var last = name.last;
// Multiple values
var ??? = name;
Constructing
Extracting
vs.
// Single values
let name = {};
name.first = 'Dan';
name.last = 'Rubin';
// Multiple values
let name = {
first: 'Dan',
last: 'Rubin'
};
// Single values
let first = name.first;
let last = name.last;
// Multiple values
let { first, last } = name;
let name = {
first: 'Dan',
last: 'Rubin'
};
let { first: firstName, last: lastName } = name;
// firstName = 'Dan'
// lastName = 'Rubin'
Objects
function logName({ first: firstName,
last: lastName }) {
console.log(firstName, lastName);
}
let name = {
first: 'Dan',
last: 'Rubin'
};
logName(name);
// Dan, Rubin
let [firstName, lastName] = ['Dan', 'Rubin'];
// firstName = 'Dan', lastName = 'Rubin'
Arrays
let [firstName, lastName] = ['Dan', 'Rubin'];
// firstName = 'Dan', lastName = 'Rubin'
[firstName, lastName] = [lastName, firstName];
// firstName = 'Rubin', lastName = 'Dan'
let [firstName, lastName] = ['Dan', 'Rubin'];
// firstName = 'Dan', lastName = 'Rubin'
[firstName, lastName] = [lastName, firstName];
// firstName = 'Rubin', lastName = 'Dan'
let [all, day, month, year] =
/^(\d\d)-(\d\d)-(\d\d\d\d)$/
.exec('28-08-2015');
Modules
// modules/math.js
const π = 3.14159265359;
// modules/math.js
export const π = 3.14159265359;
// modules/math.js
export const π = 3.14159265359;
// main.js
import { π } from './modules/math.js';
console.log(π); // 3.14159265359
// modules/math.js
export const π = 3.14159265359;
// main.js
import { π as pi } from './modules/math.js';
console.log(pi); // 3.14159265359
// modules/math.js
export const π = 3.14159265359;
// main.js
import { π as pi } from './modules/math.js';
pi = 3.14; // 'pi' is read-only
// modules/math.js
export const π = 3.14159265359;
export function square(x) {
return x * x;
}
// main.js
import { π as pi, square } from './modules/math.js';
console.log(square(4)); // 16
// modules/math.js
export const π = 3.14159265359;
export function square(x) {
return x * x;
}
// main.js
import * as math from './modules/math.js';
console.log(math.square(4)); // 16
console.log(math.π); // 3.14159265359
// modules/foo.js
export default function() {
console.log('bar!');
}
// script.js
import fooFunc from './modules/foo.js';
fooFunc(); // bar!
Arrow functions
(λ expressions)
1. Less typing
let arr = [1, 2, 3];
let square;
// ES5
square = arr.map(function (a) { return a * a });
// SS6
square = arr.map(a => a * a);
// ES5
function Interface() {
var that = this;
var button = document.getElementById('myButton');
button.addEventListener('click', function () {
console.log('CLICK');
that.handleClick();
});
}
Interface.prototype.handleClick = function () { ... };
// ES6
function Interface {
let button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log('CLICK');
this.handleClick();
});
}
Interface.prototype.handleClick = function () { };
2. no more 'var that = this'
Template strings
console.log('In ECMAScript 5.1 this
will result in an error.');
// Uncaught SyntaxError: Unexpected token ILLEGAL
console.log(`In ES6 this
will log with a newline.`);
// In ES6 this
// will log with a newline.
A what?
A backtick
or accent grave
So this: `
Instead of this: '
var conference = 'Frontend Conf Zürich',
topic = 'ES6';
console.log('Talking about ' + topic + ' at ' + conference);
// Talking about ES6 at Frontend Conf Zürich
let conference = 'Frontend Conf Zürich',
topic = 'ES6';
console.log(`Talking about ${topic} at ${conference}`);
// Talking about ES6 at Frontend Conf Zürich
Classes
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.fullName = function () {
return this.firstName + ' ' + this.lastName;
};
Person.prototype.toString = function () {
return 'My name is ' + this.fullName();
};
var me = new Person('Paul', 'Verbeek');
console.log(me.toString()); // Paul Verbeek
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
get fullName () {
return `${this.firstName} ${this.lastName}`;
}
toString () {
console.log(`My name is ${this.fullName}`);
}
}
let me = new Person('Paul', 'Verbeek');
console.log(me.toString()); // Paul Verbeek
class Person {
...
}
class Employee extends Person {
constructor(firstName, lastName, company) {
super(firstName, lastName);
this.company = company;
}
toString () {
return `${super.toString()}
and I work at ${this.company}`;
}
}
let me = new Employee('Paul', 'Verbeek', 'Indivirtual');
console.log(me.toString());
// My name is Paul Verbeek
// and I work at Indivirtual
Default, rest & spread parameters
multiply(3); // 6
multiply(3, 3); // 9
function multiply(x, y) {
if (typeof y === "undefined") { y = 2; }
return x * y;
}
multiply(3); // 6
multiply(3, 3); // 9
function multiply(x, y = 2) {
return x * y;
}
multiply(3); // 6
multiply(3, 3); // 9
default
function f(...foo) {
console.log(foo); // [4, 8, 15]
}
f(4, 8, 15);
...spread & ...rest
function f(...foo) {
let numbers = [...foo, 16, 23, 42]
console.log(numbers); // [4, 8, 15, 16, 23, 42]
}
f(4, 8, 15);
function logDan() {
if (true) {
let name = 'Dan Rubin';
}
console.log(name); // name is not defined
}
logDan();
'use strict';
function logDan() {
if (true) {
var _name = 'Dan Rubin';
}
console.log(name); // name is not defined
}
logDan();
function f(...foo) {
let numbers = [...foo, 16, 23, 42]
console.log(numbers); // [4, 8, 15, 16, 23, 42]
}
f(4, 8, 15);
"use strict";
function f() {
for (var _len = arguments.length, foo = Array(_len),
_key = 0; _key < _len; _key++) {
foo[_key] = arguments[_key];
}
var numbers = [].concat(foo, [16, 23, 42]);
console.log(numbers); // [4, 8, 15, 16, 23, 42]
}
f(4, 8, 15);
http://exploringjs.com/
Dr. Axel Rauschmayer
ECMAScript 6
ECMAScript 2015
ECMAScript Harmony
ECMA-262 6th edition
The ECMAScript® 2015 Language Specification
-
Binary and Octal Literals
-
Comprehension
-
Iterators
-
Generators
-
Map + Set + WeakMap + WeakSet
-
Math + Number + String + Object APIs
-
Promises
-
Proxies
-
Reflect API
-
Subclassable Built-ins
-
Symbols
-
Tail Calls
-
Unicode
http://bit.ly/es6-z
@_paulverbeek
Why are browser vendors working on making the developer's life easier, while they should be focussing on making the user's life easier?
Vasilis van Gemert
But Paul!
- Easier to write, less development time
- Code that's easier to maintain, less technical debt
- Faster code execution, happier users