ES6 Overview

Post on 15-Jul-2015

106 views 0 download

Tags:

transcript

import * as $ from 'jQuery';import svg from 'svglib';import Chart from 'Chart';

class LineChart extends Chart { constructor(series, canvas = document.body){

super(series, canvas); this.draw();

} draw() {

var plot = svg.buildLineChart(this.series);this.$canvas.append(plot);this.series.forEach(x => {

var { max, average: avg } = LineChart.getSerieData(x); super.addStats(max, avg);

}); } static getSerieData(serie) {

if (serie.length > 0){ let sum = serie.reduce((x, y) => x+y);return { max: Math.max(...series), average: sum/serie.length };

} return null;

}}

export default LineChart;

ECMAScript 2015Overview

ECMAScript 6

@brunoscopelliti

in the browser and on the server, too in a not too far future …

Object Literals ShorthandIt’s just syntactic sugar for Object literals.

var v = 42, propertyName = "count"; function fn() { console.log(v); };

// the old wayvar obj = { v: v, fn: fn, fn2: function() { /*...*/ } }; obj[propertyName] = 10;

// es6 shorthand \O/var obj = {

v, fn, fn2() { /*...*/ }, [propertyName]: 10

}

DestructuringAllows to extract values from object and array using patterns.

// ... and support default valuesvar [name, extension = ""] = "LICENSE".split("."); console.log(extension) // ""

// it works with array too!var [name, extension] = "me.jpeg".split("."); console.log(extension); // jpeg

// destructuring + object literal shorthandvar { v, fn } = obj; console.log(v); // 42

var { v: value, fn: log } = obj; console.log(value); // 42

Rest & Spread OperatorThe Spread operator turns an array into consecutive arguments in a function call. The Restoperator binds trailing parameters to an array.

var arr = [1, 2]; arr.concat([3, 4]); // [1, 2, [3, 4]] FAIL! ಥ_ಥ

[3, 4].forEach(function(x) { arr.push(x) }); // [1, 2, 3, 4] At least it works ¯\_(ツ)_/¯

// spread to the rescue!arr.concat(...[3, 4]); // [1, 2, 3, 4] \0/

// rest var [winner, ...theOthers] = ["a", "b", "c"];console.log(theOthers instanceof Array); // trueconsole.log(theOthers.length); // 2

Super-powered functionsVarargs and default parameters.

// default value for function’s arguments repeat("yo"); // yoyo

function repeat(msg, time = 2) { return msg.repeat(time);

}

// rest parametersfunction resize(width, height, ...elems){ console.log(elems); }resize(100, 100, "#box", "#photo"); // ["#box", "#photo"]

function fn(...args){ console.log(args); } fn(); // []fn(42, "bho!"); // [42, "bho!"]

Block Scoped variablesBlock scoped variable assignments with let and const.> Organized code!

if(true){ let v = 42;

}

console.log(v); // ReferenceError: v is not defined

// constantsconst pi = 3.14156;

pi = 3.14; // SyntaxError: invalid assignment to const pi

Arrow FunctionsFunction shorthand with arrow syntax, and more…

[1,2,3].reduce(function(a, b) { return a+b; });

// the syntax[1,2,3].reduce((a,b) => { console.log("oO"); return a+b; }); // 6

// and even shorter[1,2,3].reduce((a,b) => a+b);

Arrow Functions… arrow functions share the same context with their surrounding code;the context can’t be modified via call, apply nor bind.

var team = { n: "Justice League", people: ["Batman", "..."], logMember() {

// arrows have the same context (this) of their surrounding code.this.people.forEach(p => console.log(p + " is member of the " + this.n));

} }

team.logMember(); // Batman is member of the Justice League

Class sugarES6 classes are a simple sugar over the prototype-based OO pattern.

class Animal {

constructor(name) { this.name = name;

}

getName() { return this.name;

} }

var pet = new Animal("foo"); pet instanceof Animal // truepet.getName(); // foo

Fish.canSwim(); // true

var fish = new Fish("nemo"); fish instanceof Animal; // truefish instanceof Fish; // truefish.getName(); // nemo, the fish.

class Fish extends Animal { constructor(name){

// execute Animal's constructorsuper(name); this.domain = "water";

} getName() {

return super.getName() + ", the fish."; } static canSwim() {

return true; }

}

ModulesA standard module system for JavaScript.

// utils.jsexport function decode(str) { /*...*/ } export function encode(str) { /*...*/ }

// main.jsimport * as helper from 'utils';

utils.encode("foo");

Template StringsA decent string interpolation feature.

// welcome template stringvar str = `<p class="${cssClass}">${content}</p>`;

// backtick is ALT+96// progressive enhancement -_-

var cssClass = "visible"; var content = "Hello, world!";

// oldvar str = "<p class='"+cssClass+"'>"+content+"</p>";

JavaScript has not private object property.

ECMAScript 6 proposal:Object can have non-string property.

* At the end, the requisite of privateness for Symbol properties was dropped.Symbolic properties are just non-enumerable.

A new primitive type was created for this purpose, Symbol.

SymbolsA new primitive type.

var s = Symbol(); // Symbol()typeof s === "symbol" // true

var s1 = Symbol("s1"); var s2 = Symbol("s1");

s1 === s2 // false

For ... Of is a new loop construct.It allows to loop over the values of an Iterable collection.

A collection is Iterable if has a Symbol property Symbol.iteratorthat returns an Iterator.

An Iterator is an object with a next methodthat returns a { done, value } tuple.

Iterators & For ... Of loopFor ... Of loop over values of an iterable collection.

var collection = ["a", "b", "c", "d", "e", "f", "g"];

for(value of collection){ console.log(value);

}

// "a", "b", "c", "d", "e", "f", "g"

// custom iteration

collection[Symbol.iterator] = function() { var index = 0; return {

next: () => { if (index < this.length) {

let obj = { done: false, value: this[index] }; index = index + 2; return obj;

} else { return { done: true };

} }

} }

for(value of collection){ console.log(value); } // "a", "c", "e", "g"

Generator FunctionsAre functions which can be interrupted, and then resumed, used to create Iterators.The yield operator is used to interrupt the execution. The generator execution resumes when the iterator’s next method is called.

collection[Symbol.iterator] = function* () { for (let i=0; i<this.length; i++) {

if (i%2 === 0) yield this[i]; }

};

for(value of collection){ console.log(value); } // "a", "c", "e", "g"

SetAn ordered collection with no duplicates.

* Set has a rich prototype that expose method to work with the set instance.

var arr = [1, 2, 2, 3, 3, 3, 4]; var set = new Set(arr);

set; // Set {1, 2, 3, 4}

MapAn ordered collection of {key, value} tuples, without duplicated keys.

* Map has a rich prototype that expose method to work with the map instance.

var arr = [ [1, "first"], [1, "one"], [2, "two"] ]; var map = new Map(arr);

map; // Map { 1: "one", 2: "two" }

ProxiesAllows to intercept, and re-implement, operations executed over an object.

var obj = { v: 42 }; var traps = {

set(target, propKey, value, receiver) { console.log('SET '+propKey+'='+value);target[propKey] = value;

} };

var proxy = new Proxy(obj, traps); proxy.v = 0;

// SET v=0

PromisesExecute asynchronous code like if it’s synchronous

function getJSON() { return new Promise(function(resolve, reject) {

setTimeout(function() { resolve('{"value": 42}'); }, 500); });

}

getJSON().then(function(resp) { console.log("success", resp);

});

ReflectionReflect is a built-in object that provides methods for interceptable JavaScript operations

var obj = { v: 42 };

var proxy = new Proxy(obj, { set(target, propKey, value, receiver) {

console.log('SET '+propKey+'='+value); Reflect.set(target, propKey, value, receiver);

} });

Did you like this?

... what about the browser support?

//kangax.github.io/compat-table/es6/

2015:This is no more a problem!

var team = { name: "Justice League", members: [ { name: "Batman", gender: "M" }, { name: "Wonder woman", gender: "F" }

], add(...members) { this.members.push(...members)

},remove(name) { let memberIndex = this.members.findIndex(x => x.name === name); if (memberIndex >= 0){this.members.splice(memberIndex, 1);

} }, log(gender = "M") { this.members.filter(x => x.gender === gender) .forEach(h => console.log(`${h.name} is member of the ${this.name}`)); }

}

team.add({ name: "Gipsy", gender: "F" }); team.add({ name: "Flash", gender: "M" }, { name: "Green Lantern", gender: "M" });

team.remove("Batman")

team.log("M"); team.log("F");

var team = { name: "Justice League", members: [{ name: "Batman", gender: "M" }, { name: "Wonder woman", gender: "F" }

], add: function add() { var _members, _len = arguments.length;for (var members = _len, _key = 0; _key < _len; _key++){ members[_key] = arguments[_key];

} (_members = this.members).push.apply(_members, members);

}, remove: function remove(name) { var memberIndex = this.members.findIndex(function (x){ return x.name === name;

}); if (memberIndex >= 0) { this.members.splice(memberIndex, 1);

} }, log: function log() { var _this = this; var gender = arguments[0] === undefined ? "M" : arguments[0]; this.members.filter(function (x) { return x.gender === gender; }).forEach(function (h) { return console.log("" + h.name + " is member of the " + _this.name); });

} };

Grazie!