KEMBAR78
Introduction to ECMAScript 2015 | PDF
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/