ECMAScript 2015 Tomasz Dziuda meet.js Łódź @ 9.VI.2015
About me @dziudek dziudek@gmail.com http://dziudek.pl Lead Developer @ GavickPro Organizer of: • WordUp Łódź, • JoomlaDay Poland 2013, • WordCamp Poland 2014, • WordCamp Poland 2015
http://dziudek.github.io/dev-links/
ES2015 Today
Source: http://kangax.github.io/compat-table/es6/
 screenshot from: 31/5/2015
https://babeljs.io/
ES2015 Features
Enhanced Object Literals
var car = { speed: 100, getSpeed() { return this.speed; } } // car.speed() => 100;
var chapter = 2; var bookState = { [“ch” + chapter]: “Chapter ” + chapter, [“getChapter” + chapter]() { return this[“ch” + chapter]; } } // bookState.ch2 => “Chapter 2” // bookState.getChapter2() => “Chapter 2”
Classes
class Person { constructor(name, age) { this.name = name; this.age = age } toString() { return “Person: ” + this.name; } }
Inheritance
class Person extends Mammal { constructor(name, age) { super(); this.name = name; this.age = age } toString() { return “Person: ” + this.name; } }
static, get, set
class URLHelper { static hashVal() { return location.hash.replace(‘#’,’’); } } URLHelper.hashVal(); // http://domain.com/#top => “top”
class Person { constructor(name, age) { this._name = name; this._age = age } get name() { return this._name; } set name(newName) { this._name = newName; } }
Built-ins subclassing
class MyArray extends Array { last() { return this[this.length - 1]; } }
Abstract classes
class Base { constructor () { if (new.target === Base) { throw TypeError("new of abstract class Base”); } } }
Modules
// file helper/linker.js export var separator = ‘,’; export function link (arr) { return arr.join(separator); }
// file helper/linker.js export {separator}; export {separator as s}; export {separator} from “linker”; export {separator as s} from “linker”;
// file app.js import {separator, link} from ‘helper/linker’;
// file app.js import {separator, link} from ‘helper/linker’; // file app.js import * as linker from ‘helper/linker’; // linker.separator / linker.link
// file app.js import {separator, link} from ‘helper/linker’; // file app.js import * as linker from ‘helper/linker’; // linker.separator / linker.link // file app.js import {separator as s} from ‘helper/linker’;
// file helper/linker.js export var separator = ‘,’; export default function(arr) { return arr.join(separator); }
// file app.js import link from ‘helper/linker’;
// file app.js import link from ‘helper/linker’; // file app.js import link, {separator} from ‘helper/linker’;
Template Strings
var msg = `<ul> <li>Item I</li> <li>Item II</li> <li>Item III</li> <li>Item IV</li> <li>Item V</li> </ul>`;
var username = “John”; var msg = `Hello, ${username}`; // msg returns “Hello, John”
var firstname = “John”; var lastname = “ Doe” var msg = `Hello, ${firstname + lastname}`; // msg returns “Hello, John Doe”
var fName = “John”; var msg = `Hello, ${fName.toUpperCase()}`; // msg returns “Hello, JOHN”
var total = 100; var VAT = 23; var finalPrice = ‘’; // we’ll have an error without it var msg = parseVAT`Sum: ${total} + VAT ${VAT}% = ${finalPrice}`; // "Sum: 100 + VAT 23% = 123"
function parseVAT(parts, total, VAT) { var output = "", i = 0; while (i < parts.length) { output += parts[i++]; if (i < arguments.length) { output += arguments[i]; } if(i === 3){ output += total * (100 + VAT) / 100.0; } } return output; }
function parseVAT(parts, total, VAT) { var output = "", i = 0; while (i < parts.length) { output += parts[i++]; if (i < arguments.length) { output += arguments[i]; } if(i === 3){ output += total * (100 + VAT) / 100.0; } } return output; }
function parseVAT(parts, total, VAT) { var output = "", i = 0; while (i < parts.length) { output += parts[i++]; if (i < arguments.length) { output += arguments[i]; } if(i === 3){ output += total * (100 + VAT) / 100.0; } } return output; }
function parseVAT(parts, total, VAT) { var output = "", i = 0; while (i < parts.length) { output += parts[i++]; if (i < arguments.length) { output += arguments[i]; } if(i === 3){ output += total * (100 + VAT) / 100.0; } } return output; }
http://jsperf.com/es6-string-literals-vs-string-concatenation
http://jsperf.com/es6-string-literals-vs-string-concatenation
Constants
const PI = 3.141593; const ĘĆ = 1.858407; var pięć = PI + ĘĆ;
const PI = 3.141593; PI = 3.14; // not work const person = { name: “John” }; person.name = “Adam”; // Correct - use Object.freeze person.age = 25; // Correct - use Object.seal
const PI = 3.141593; PI = 3.14; // not work const person = { name: “John” }; person.name = “Adam”; // Correct - use Object.freeze person.age = 25; // Correct - use Object.seal
const PI = 3.141593; PI = 3.14; // not work const person = { name: “John” }; person.name = “Adam”; // Correct - use Object.freeze person.age = 25; // Correct - use Object.seal
Block scope
{ function test() { return 1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
{ function test() { return 1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
{ function test() { return 1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
{ function test() { return 1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
{ function test() { return 1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
var arr = [1,2,3]; for (let i = 0; i < arr.length; i++) { var temp = arr[i]; } console.log(i); // undefined console.log(temp); // 3
let name = “John”; let name = “Alex”; // Error
Arrow functions
function (fName, lName) { return fName + ‘ ‘ + lName; }
(fName, lName) => fName + ‘ ‘ + lName;
[1, 2, 3].map(n => n * 2); [1,2,3].filter(n => n % 2 === 0); var person = () => ({name:“John”, age:25});
[1, 2, 3].map(n => n * 2); [1,2,3].filter(n => n % 2 === 0); var person = () => ({name:“John”, age:25});
[1, 2, 3].map(n => n * 2); [1,2,3].filter(n => n % 2 === 0); var person = () => ({name:“John”, age:25});
function Timer(){ this.time = 0; setInterval(function() { this.time++; // won’t work }, 1000); } var t = new Timer();
function Timer(){ this.time = 0; // below line will affect the time setInterval(() => this.time++, 1000); } var t = new Timer();
fetch(url).then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log(“Error!”));
Shorthand assignment
let name = “John”; let person = {name}; // person = {name: “John”}
let name = “John”; let person = {name}; // person = {name: “John”}
Destructuring
var x = 1; var y = 2; [x, y] = [y, x]; // x=2, y=1
function names() { return [“John”, “Alex“]; } var p1, p2; [p1, p2] = names();
function names() { return [“John”, “Alex“, “Max”]; } var p1, p2; [p1, ,p2] = names();
var names = ["Alex", "John", "Max"]; var [p1, p2, p3] = names;
var names = { p1:“Alex”, p2:”John", p3:”Max” }; var {p1, p2, p3} = names; /* p1 = Alex p2 = John p3 = Max */
function date({ day:d, month:m, year:y }) { return d + ‘-’ + m + ‘-’ + y; } date({ day: 20, month: 10, year: 1988 });
Better parameter handling
function power(x, y = 2) { return Math.pow(x, y); } // f(2) => 4
function names(x, ...y) { return 1 + y.length; } // names(“Alex”, “John”, “Max”) => 3
function names(x, y, z) { return x + “ ” + y + “ ” + z; } names(…[“Alex”, “John”, “Max”]);
var a = [3,4,5]; var b = [1,2, …a]; // b => [1,2,3,4,5]
Symbols
let symbol1 = Symbol(“test”); let symbol2 = Symbol(“test”); symbol1 === symbol2 // False
let objWithSymbol = { [Symbol(“year”)]: 2015 } console.log(objWithSymbol); // {}
let objWithSymbol = { [Symbol(“year”)]: 2015 } console.log(objWithSymbol); // {} Object.getOwnPropertySymbols(objWithSymbol); // [Symbol(year)]
Iterators & Generators
let iterable = “abc”[Symbol.iterator](); iterable.next(); // { value: “a”, done: false } iterable.next(); // { value: “b”, done: false } iterable.next(); // { value: “c”, done: false } iterable.next(); // { value: undefined, done: true }
Iterable • Array • String • Map • Set • arguments • DOM queries
for .. of
for(let div of document.querySelectorAll('div')) { div.style.border = "1px solid red"; }
var obj = { items: [1,2,3,4,5], [Symbol.iterator]() { let i = 0; let self = this; return { next() { return { done: (i >= self.items.length), value: self.items[i++] } } } } }
for(let n of obj) { console.log(n); } // 1 // 2 // 3 // 4 // 5
function* gen(start, stop) { while(start <= stop) { yield start; start++; } }
var r = gen(0, 2); r.next(); // {value: 0, done: false} r.next(); // {value: 1, done: false} r.next(); // {value: 2, done: false} r.next(); // {value: undefined, done: true}
function* gen() { yield ‘start’; yield ‘middle’; yield ‘stop’; } var g = gen(); g.next(); // { value: ‘start’, done: false} g.next(); // { value: ‘middle’, done: false} g.next(); // { value: ‘stop’, done: false}
function* odd(max) { for(var i = 0; i <= max; i++) { if(i % 2) yield i; } } let odds = […odd(20)] // [1,3,5,7,9,11,13,15,17,19]
function* odd(max) { for(var i = 0; i <= max; i++) { if(i % 2) yield i; } } let odds = […odd(20)] // odds = [1,3,5,7,9,11,13,15,17,19]
let odds = []; for (let n of odd(20)) { odds.push(n); } // odds = [1,3,5,7,9,11,13,15,17,19]
Promises
Promise states • pending === !fulfilled && !rejected • fulfilled === success • rejected === fail
function readFile(filename) { return new Promise(function(fulfill, reject) { fs.readFile(filename, encoding, function(err, res) { if(err) reject(err); else fulfill(res); }); }); }
function readFile(filename) { return new Promise(function(fulfill, reject) { fs.readFile(filename, encoding, function(err, res) { if(err) reject(err); else fulfill(res); }); }); }
function readFile(filename) { return new Promise(function(fulfill, reject) { fs.readFile(filename, encoding, function(err, res) { if(err) reject(err); else fulfill(res); }); }); }
function readFile(filename) { return new Promise(function(fulfill, reject) { fs.readFile(filename, encoding, function(err, res) { if(err) reject(err); else fulfill(res); }); }); }
readFile(‘data.json’, 'utf8').then(function (res){ return JSON.parse(res); });
readFile(‘data.json’, 'utf8').then(function (res){ return JSON.parse(res); });
readFile(‘data.json’, 'utf8').then(function (res){ return JSON.parse(res); }, function (err) { console.log(err); });
readFile(‘data.json’, 'utf8').then(function (res){ return JSON.parse(res); }).catch(function(err) { console.log(err); });
Promise.all([ readFile(‘data1.json’, 'utf8'), readFile(‘data2.json’, 'utf8'), readFile(‘data3.json’, 'utf8') ]).then((data) => { let [ f1, f2, f3 ] = data; });
Promise.all([ readFile(‘data1.json’, 'utf8'), readFile(‘data2.json’, 'utf8'), readFile(‘data3.json’, 'utf8') ]).then((data) => { let [ f1, f2, f3 ] = data; });
Promise.all([ readFile(‘data1.json’, 'utf8'), readFile(‘data2.json’, 'utf8'), readFile(‘data3.json’, 'utf8') ]).then((data) => { let [ f1, f2, f3 ] = data; });
Promise.race([ readFile(‘data1.json’, 'utf8'), readFile(‘data2.json’, 'utf8'), readFile(‘data3.json’, 'utf8') ]).then((data) => { let fastest = data; });
Proxies
var obj = {}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
var obj = {}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
var obj = {}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
var obj = {}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
var obj = {}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
Maps & Sets
Set • Used to store unique values • Iterable • Easily accessible size
var names = new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
var names = new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
var names = new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
var names = new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
var names = new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
for (let name of names) { console.log(name); } let nameArr = […names]; for (let name of names.keys()) { console.log(name); } // names.keys() === names.values()
for (let name of names) { console.log(name); } let nameArr = […names]; for (let name of names.keys()) { console.log(name); } // names.keys() === names.values()
for (let name of names) { console.log(name); } let nameArr = […names]; for (let name of names.keys()) { console.log(name); } // names.keys() === names.values()
Map • Used to store values connected with unique keys • Iterable • Easily accessible size • key can be primitive, object or even function
var relations = new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
var relations = new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
var relations = new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
var relations = new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
var relations = new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
for (let [key, value] of relations) { console.log(key + “ & ” + value); } for (let [key, value] of relations.entries()) { console.log(key + “ & ” + value); } for (let key of relations.keys()) { console.log(key); }
WeakMap vs. Map • Doesn’t prevent GC • no information about size • Key can be only an object (function is object too)
let privateData = new WeakMap(); class MyClass { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } }
let privateData = new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } }
let privateData = new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } }
let privateData = new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } }
// Without WeakMap let p1 = new Person(“John”, 25); let p2 = new Person(“Adam”, 40); privateData.size; // 2 p1 = null; privateData.size; // 2
// Without WeakMap let p1 = new Person(“John”, 25); let p2 = new Person(“Adam”, 40); privateData.size; // 2 p1 = null; privateData.size; // 2
WeakSet vs. Set • Doesn’t prevent GC • non-iterable • non-accessible element values • no information about size • key can be only an object
Built-in Methods
[1, 5, 3, 8].find(x => x > 2); // 5 “- ”.repeat(3); // “- - - ” Object.assign(obj, {“a”: 1}, {“b”: 2}); // obj = {“a”: 1, “b”: 2} Math.sign(25); // 1 Math.sign(0); // 0 Math.sign(-25); // -1
[1, 5, 3, 8].find(x => x > 2); // 5 “- ”.repeat(3); // “- - - ” Object.assign(obj, {“a”: 1}, {“b”: 2}); // obj = {“a”: 1, “b”: 2} Math.sign(25); // 1 Math.sign(0); // 0 Math.sign(-25); // -1
[1, 5, 3, 8].find(x => x > 2); // 5 “- ”.repeat(3); // “- - - ” Object.assign(obj, {“a”: 1}, {“b”: 2}); // obj = {“a”: 1, “b”: 2} Math.sign(25); // 1 Math.sign(0); // 0 Math.sign(-25); // -1
[1, 5, 3, 8].find(x => x > 2); // 5 “- ”.repeat(3); // “- - - ” Object.assign(obj, {“a”: 1}, {“b”: 2}); // obj = {“a”: 1, “b”: 2} Math.sign(25); // 1 Math.sign(0); // 0 Math.sign(-25); // -1
… and much more
https://github.com/lukehoban/es6features#math--number-- string--array--object-apis
Useful links • http://www.2ality.com/2015/02/es6-classes-final.html • http://pouchdb.com/2015/05/18/we-have-a-problem-with- promises.html • http://kangax.github.io/compat-table/es6/ • https://github.com/lukehoban/es6features • http://es6-features.org/ • http://ilikekillnerds.com/2015/02/what-are-weakmaps-in- es6/

Introduction to ECMAScript 2015

  • 1.
  • 2.
    About me @dziudek dziudek@gmail.com http://dziudek.pl Lead Developer@ GavickPro Organizer of: • WordUp Łódź, • JoomlaDay Poland 2013, • WordCamp Poland 2014, • WordCamp Poland 2015
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
    var car ={ speed: 100, getSpeed() { return this.speed; } } // car.speed() => 100;
  • 10.
    var chapter =2; var bookState = { [“ch” + chapter]: “Chapter ” + chapter, [“getChapter” + chapter]() { return this[“ch” + chapter]; } } // bookState.ch2 => “Chapter 2” // bookState.getChapter2() => “Chapter 2”
  • 11.
  • 12.
    class Person { constructor(name,age) { this.name = name; this.age = age } toString() { return “Person: ” + this.name; } }
  • 13.
  • 14.
    class Person extendsMammal { constructor(name, age) { super(); this.name = name; this.age = age } toString() { return “Person: ” + this.name; } }
  • 15.
  • 16.
    class URLHelper { statichashVal() { return location.hash.replace(‘#’,’’); } } URLHelper.hashVal(); // http://domain.com/#top => “top”
  • 17.
    class Person { constructor(name,age) { this._name = name; this._age = age } get name() { return this._name; } set name(newName) { this._name = newName; } }
  • 18.
  • 19.
    class MyArray extendsArray { last() { return this[this.length - 1]; } }
  • 20.
  • 21.
    class Base { constructor() { if (new.target === Base) { throw TypeError("new of abstract class Base”); } } }
  • 22.
  • 23.
    // file helper/linker.js exportvar separator = ‘,’; export function link (arr) { return arr.join(separator); }
  • 24.
    // file helper/linker.js export{separator}; export {separator as s}; export {separator} from “linker”; export {separator as s} from “linker”;
  • 25.
    // file app.js import{separator, link} from ‘helper/linker’;
  • 26.
    // file app.js import{separator, link} from ‘helper/linker’; // file app.js import * as linker from ‘helper/linker’; // linker.separator / linker.link
  • 27.
    // file app.js import{separator, link} from ‘helper/linker’; // file app.js import * as linker from ‘helper/linker’; // linker.separator / linker.link // file app.js import {separator as s} from ‘helper/linker’;
  • 28.
    // file helper/linker.js exportvar separator = ‘,’; export default function(arr) { return arr.join(separator); }
  • 29.
    // file app.js importlink from ‘helper/linker’;
  • 30.
    // file app.js importlink from ‘helper/linker’; // file app.js import link, {separator} from ‘helper/linker’;
  • 31.
  • 32.
    var msg =`<ul> <li>Item I</li> <li>Item II</li> <li>Item III</li> <li>Item IV</li> <li>Item V</li> </ul>`;
  • 33.
    var username =“John”; var msg = `Hello, ${username}`; // msg returns “Hello, John”
  • 34.
    var firstname =“John”; var lastname = “ Doe” var msg = `Hello, ${firstname + lastname}`; // msg returns “Hello, John Doe”
  • 35.
    var fName =“John”; var msg = `Hello, ${fName.toUpperCase()}`; // msg returns “Hello, JOHN”
  • 36.
    var total =100; var VAT = 23; var finalPrice = ‘’; // we’ll have an error without it var msg = parseVAT`Sum: ${total} + VAT ${VAT}% = ${finalPrice}`; // "Sum: 100 + VAT 23% = 123"
  • 37.
    function parseVAT(parts, total,VAT) { var output = "", i = 0; while (i < parts.length) { output += parts[i++]; if (i < arguments.length) { output += arguments[i]; } if(i === 3){ output += total * (100 + VAT) / 100.0; } } return output; }
  • 38.
    function parseVAT(parts, total,VAT) { var output = "", i = 0; while (i < parts.length) { output += parts[i++]; if (i < arguments.length) { output += arguments[i]; } if(i === 3){ output += total * (100 + VAT) / 100.0; } } return output; }
  • 39.
    function parseVAT(parts, total,VAT) { var output = "", i = 0; while (i < parts.length) { output += parts[i++]; if (i < arguments.length) { output += arguments[i]; } if(i === 3){ output += total * (100 + VAT) / 100.0; } } return output; }
  • 40.
    function parseVAT(parts, total,VAT) { var output = "", i = 0; while (i < parts.length) { output += parts[i++]; if (i < arguments.length) { output += arguments[i]; } if(i === 3){ output += total * (100 + VAT) / 100.0; } } return output; }
  • 41.
  • 42.
  • 43.
  • 44.
    const PI =3.141593; const ĘĆ = 1.858407; var pięć = PI + ĘĆ;
  • 45.
    const PI =3.141593; PI = 3.14; // not work const person = { name: “John” }; person.name = “Adam”; // Correct - use Object.freeze person.age = 25; // Correct - use Object.seal
  • 46.
    const PI =3.141593; PI = 3.14; // not work const person = { name: “John” }; person.name = “Adam”; // Correct - use Object.freeze person.age = 25; // Correct - use Object.seal
  • 47.
    const PI =3.141593; PI = 3.14; // not work const person = { name: “John” }; person.name = “Adam”; // Correct - use Object.freeze person.age = 25; // Correct - use Object.seal
  • 48.
  • 49.
    { function test() { return1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
  • 50.
    { function test() { return1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
  • 51.
    { function test() { return1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
  • 52.
    { function test() { return1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
  • 53.
    { function test() { return1; } test() === 1; // True { function test() { return 2; } test() === 2; // True } test() === 1; // Still true }
  • 54.
    var arr =[1,2,3]; for (let i = 0; i < arr.length; i++) { var temp = arr[i]; } console.log(i); // undefined console.log(temp); // 3
  • 55.
    let name =“John”; let name = “Alex”; // Error
  • 56.
  • 57.
    function (fName, lName){ return fName + ‘ ‘ + lName; }
  • 58.
    (fName, lName) =>fName + ‘ ‘ + lName;
  • 59.
    [1, 2, 3].map(n=> n * 2); [1,2,3].filter(n => n % 2 === 0); var person = () => ({name:“John”, age:25});
  • 60.
    [1, 2, 3].map(n=> n * 2); [1,2,3].filter(n => n % 2 === 0); var person = () => ({name:“John”, age:25});
  • 61.
    [1, 2, 3].map(n=> n * 2); [1,2,3].filter(n => n % 2 === 0); var person = () => ({name:“John”, age:25});
  • 62.
    function Timer(){ this.time =0; setInterval(function() { this.time++; // won’t work }, 1000); } var t = new Timer();
  • 63.
    function Timer(){ this.time =0; // below line will affect the time setInterval(() => this.time++, 1000); } var t = new Timer();
  • 64.
    fetch(url).then(response => response.json()) .then(data=> console.log(data)) .catch(e => console.log(“Error!”));
  • 65.
  • 66.
    let name =“John”; let person = {name}; // person = {name: “John”}
  • 67.
    let name =“John”; let person = {name}; // person = {name: “John”}
  • 68.
  • 69.
    var x =1; var y = 2; [x, y] = [y, x]; // x=2, y=1
  • 70.
    function names() { return[“John”, “Alex“]; } var p1, p2; [p1, p2] = names();
  • 71.
    function names() { return[“John”, “Alex“, “Max”]; } var p1, p2; [p1, ,p2] = names();
  • 72.
    var names =["Alex", "John", "Max"]; var [p1, p2, p3] = names;
  • 73.
    var names ={ p1:“Alex”, p2:”John", p3:”Max” }; var {p1, p2, p3} = names; /* p1 = Alex p2 = John p3 = Max */
  • 74.
    function date({ day:d,month:m, year:y }) { return d + ‘-’ + m + ‘-’ + y; } date({ day: 20, month: 10, year: 1988 });
  • 75.
  • 76.
    function power(x, y= 2) { return Math.pow(x, y); } // f(2) => 4
  • 77.
    function names(x, ...y){ return 1 + y.length; } // names(“Alex”, “John”, “Max”) => 3
  • 78.
    function names(x, y,z) { return x + “ ” + y + “ ” + z; } names(…[“Alex”, “John”, “Max”]);
  • 79.
    var a =[3,4,5]; var b = [1,2, …a]; // b => [1,2,3,4,5]
  • 80.
  • 81.
    let symbol1 =Symbol(“test”); let symbol2 = Symbol(“test”); symbol1 === symbol2 // False
  • 82.
    let objWithSymbol ={ [Symbol(“year”)]: 2015 } console.log(objWithSymbol); // {}
  • 83.
    let objWithSymbol ={ [Symbol(“year”)]: 2015 } console.log(objWithSymbol); // {} Object.getOwnPropertySymbols(objWithSymbol); // [Symbol(year)]
  • 84.
  • 85.
    let iterable =“abc”[Symbol.iterator](); iterable.next(); // { value: “a”, done: false } iterable.next(); // { value: “b”, done: false } iterable.next(); // { value: “c”, done: false } iterable.next(); // { value: undefined, done: true }
  • 86.
    Iterable • Array • String •Map • Set • arguments • DOM queries
  • 87.
  • 88.
    for(let div ofdocument.querySelectorAll('div')) { div.style.border = "1px solid red"; }
  • 89.
    var obj ={ items: [1,2,3,4,5], [Symbol.iterator]() { let i = 0; let self = this; return { next() { return { done: (i >= self.items.length), value: self.items[i++] } } } } }
  • 90.
    for(let n ofobj) { console.log(n); } // 1 // 2 // 3 // 4 // 5
  • 91.
    function* gen(start, stop){ while(start <= stop) { yield start; start++; } }
  • 92.
    var r =gen(0, 2); r.next(); // {value: 0, done: false} r.next(); // {value: 1, done: false} r.next(); // {value: 2, done: false} r.next(); // {value: undefined, done: true}
  • 93.
    function* gen() { yield‘start’; yield ‘middle’; yield ‘stop’; } var g = gen(); g.next(); // { value: ‘start’, done: false} g.next(); // { value: ‘middle’, done: false} g.next(); // { value: ‘stop’, done: false}
  • 94.
    function* odd(max) { for(vari = 0; i <= max; i++) { if(i % 2) yield i; } } let odds = […odd(20)] // [1,3,5,7,9,11,13,15,17,19]
  • 95.
    function* odd(max) { for(vari = 0; i <= max; i++) { if(i % 2) yield i; } } let odds = […odd(20)] // odds = [1,3,5,7,9,11,13,15,17,19]
  • 96.
    let odds =[]; for (let n of odd(20)) { odds.push(n); } // odds = [1,3,5,7,9,11,13,15,17,19]
  • 97.
  • 98.
    Promise states • pending=== !fulfilled && !rejected • fulfilled === success • rejected === fail
  • 99.
    function readFile(filename) { returnnew Promise(function(fulfill, reject) { fs.readFile(filename, encoding, function(err, res) { if(err) reject(err); else fulfill(res); }); }); }
  • 100.
    function readFile(filename) { returnnew Promise(function(fulfill, reject) { fs.readFile(filename, encoding, function(err, res) { if(err) reject(err); else fulfill(res); }); }); }
  • 101.
    function readFile(filename) { returnnew Promise(function(fulfill, reject) { fs.readFile(filename, encoding, function(err, res) { if(err) reject(err); else fulfill(res); }); }); }
  • 102.
    function readFile(filename) { returnnew Promise(function(fulfill, reject) { fs.readFile(filename, encoding, function(err, res) { if(err) reject(err); else fulfill(res); }); }); }
  • 103.
  • 104.
  • 105.
    readFile(‘data.json’, 'utf8').then(function (res){ returnJSON.parse(res); }, function (err) { console.log(err); });
  • 106.
    readFile(‘data.json’, 'utf8').then(function (res){ returnJSON.parse(res); }).catch(function(err) { console.log(err); });
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
    var obj ={}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
  • 113.
    var obj ={}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
  • 114.
    var obj ={}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
  • 115.
    var obj ={}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
  • 116.
    var obj ={}; var observed = new Proxy(obj, { set(target, key, value, receiver) { console.log(key+'='+value); target[key] = value; } }); observed.x = 10; // x = 10
  • 117.
  • 118.
    Set • Used tostore unique values • Iterable • Easily accessible size
  • 119.
    var names =new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
  • 120.
    var names =new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
  • 121.
    var names =new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
  • 122.
    var names =new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
  • 123.
    var names =new Set(); names.add(“Doe”); names.add(“Johnson”); names.has(“Doe”); // true names.size; // 2 names.delete(“Johnson”); // true names.size; // 1
  • 124.
    for (let nameof names) { console.log(name); } let nameArr = […names]; for (let name of names.keys()) { console.log(name); } // names.keys() === names.values()
  • 125.
    for (let nameof names) { console.log(name); } let nameArr = […names]; for (let name of names.keys()) { console.log(name); } // names.keys() === names.values()
  • 126.
    for (let nameof names) { console.log(name); } let nameArr = […names]; for (let name of names.keys()) { console.log(name); } // names.keys() === names.values()
  • 127.
    Map • Used tostore values connected with unique keys • Iterable • Easily accessible size • key can be primitive, object or even function
  • 128.
    var relations =new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
  • 129.
    var relations =new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
  • 130.
    var relations =new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
  • 131.
    var relations =new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
  • 132.
    var relations =new Map(); relations.set(“John”, “Mary”); relations.set(“Adam”, “Eve”); relations.size; // 2 relations.get(“Adam”); // “Eve” relations.delete(“Adam”); // true relations.size; // 1
  • 133.
    for (let [key,value] of relations) { console.log(key + “ & ” + value); } for (let [key, value] of relations.entries()) { console.log(key + “ & ” + value); } for (let key of relations.keys()) { console.log(key); }
  • 134.
    WeakMap vs. Map •Doesn’t prevent GC • no information about size • Key can be only an object (function is object too)
  • 135.
    let privateData =new WeakMap(); class MyClass { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } }
  • 136.
    let privateData =new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } }
  • 137.
    let privateData =new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } }
  • 138.
    let privateData =new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } }
  • 139.
    // Without WeakMap letp1 = new Person(“John”, 25); let p2 = new Person(“Adam”, 40); privateData.size; // 2 p1 = null; privateData.size; // 2
  • 140.
    // Without WeakMap letp1 = new Person(“John”, 25); let p2 = new Person(“Adam”, 40); privateData.size; // 2 p1 = null; privateData.size; // 2
  • 141.
    WeakSet vs. Set •Doesn’t prevent GC • non-iterable • non-accessible element values • no information about size • key can be only an object
  • 142.
  • 143.
    [1, 5, 3,8].find(x => x > 2); // 5 “- ”.repeat(3); // “- - - ” Object.assign(obj, {“a”: 1}, {“b”: 2}); // obj = {“a”: 1, “b”: 2} Math.sign(25); // 1 Math.sign(0); // 0 Math.sign(-25); // -1
  • 144.
    [1, 5, 3,8].find(x => x > 2); // 5 “- ”.repeat(3); // “- - - ” Object.assign(obj, {“a”: 1}, {“b”: 2}); // obj = {“a”: 1, “b”: 2} Math.sign(25); // 1 Math.sign(0); // 0 Math.sign(-25); // -1
  • 145.
    [1, 5, 3,8].find(x => x > 2); // 5 “- ”.repeat(3); // “- - - ” Object.assign(obj, {“a”: 1}, {“b”: 2}); // obj = {“a”: 1, “b”: 2} Math.sign(25); // 1 Math.sign(0); // 0 Math.sign(-25); // -1
  • 146.
    [1, 5, 3,8].find(x => x > 2); // 5 “- ”.repeat(3); // “- - - ” Object.assign(obj, {“a”: 1}, {“b”: 2}); // obj = {“a”: 1, “b”: 2} Math.sign(25); // 1 Math.sign(0); // 0 Math.sign(-25); // -1
  • 147.
  • 148.
  • 149.
    Useful links • http://www.2ality.com/2015/02/es6-classes-final.html •http://pouchdb.com/2015/05/18/we-have-a-problem-with- promises.html • http://kangax.github.io/compat-table/es6/ • https://github.com/lukehoban/es6features • http://es6-features.org/ • http://ilikekillnerds.com/2015/02/what-are-weakmaps-in- es6/