Upgrade to Pro — share decks privately, control downloads, hide ads and more …

From ES5 to ES6 - 2018 Edition

From ES5 to ES6 - 2018 Edition

An introduction to ES6 features like:
– let vs var vs const
– function
– template string
– enhanced object
– destructuring
– classes
– modules
– promises
– symbols
– Map, Set, WeakMap, WeakSet
– metaprogramming

Stefano Sala

March 26, 2018
Tweet

Other Decks in Programming

Transcript

  1. AN INTRODUCTION TO ES6 FEATURES 2 core features overview AN

    INTRODUCTION TO ES6 FEATURES MODULO 1 – FROM ES5 TO ES6 Stefano Sala
  2. ECMAScript ECMAScript (or ES) is a trademarked scripting-language specification standardized

    by Ecma International in ECMA-262 and ISO/IEC 16262. It was created to standardize JavaScript, so as to foster multiple independent implementations. JavaScript has remained the best-known implementation of ECMAScript since the standard was first published, with other well-known implementations including JScript and ActionScript. Coders commonly use ECMAScript for client-side scripting on the World Wide Web, and it is increasingly being used for writing server applications and services using Node.js. AN INTRODUCTION TO ES6 FEATURES 3
  3. global scope var userId = 1; let postId = 200;

    const siteId = 4; console.log( window.userId ); // 1 console.log( window.postId ); // undefined console.log( window.siteId ); // undefined AN INTRODUCTION TO ES6 FEATURES 6
  4. function scope function getIds() { var userId = 1; let

    postId = 200; const siteId = 4; } console.log( window.userId ); // undefined console.log( window.postId ); // undefined console.log( window.siteId ); // undefined AN INTRODUCTION TO ES6 FEATURES 8
  5. block scope { var userId = 1; let postId =

    200; const siteId = 4; console.log( userId ); // 1 console.log( postId ); // 200 console.log( siteId ); // 4 } console.log( userId ); // 1 console.log( postId ); // Uncaught ReferenceError: postId is not defined console.log( siteId ); // Uncaught ReferenceError: siteId is not defined AN INTRODUCTION TO ES6 FEATURES 10
  6. can be reassigned const post = {}; const ids =

    [ 1, 2, 3 ]; const id = 1; post = "Hello world!"; // Uncaught TypeError: Assignment to constant variable. post.title = "Hello world!"; delete post.title; ids.push( 4 ); ids = [ 7, 8, 9 ]; // Uncaught TypeError: Assignment to constant variable. id++; // Uncaught TypeError: Assignment to constant variable. Const has immutable binding NOT immutability AN INTRODUCTION TO ES6 FEATURES 12
  7. Conclusion • If you are using ES6 use const by

    default. • If you think that current variable might be re-assigned in the future use let instead. • You should forget about var, and in most cases all your var keywords could be replaced with let straight away! AN INTRODUCTION TO ES6 FEATURES 14
  8. var declarations and hoisting JavaScript engine changes the code to

    function doSomething(condition) { var color; if (condition) { color = 'blue'; // other code } else { // color exist here with value of undefined } // color exist here with value of undefined } function doSomething(condition) { if (condition) { var color = 'blue'; // other code } else { // color exist here with value of undefined } // color exist here with value of undefined } AN INTRODUCTION TO ES6 FEATURES 15 console.log(value); // Uncaught ReferenceError: value is not defined
  9. The Temporal Dead Zone const abc = 10; if(true) {

    console.log(typeof abc); // Uncaught ReferenceError: abc is not defined let abc = 'test'; console.log(typeof abc); // string } console.log(typeof abc); // number console.log(typeof value); // undefined console.log(typeof myConst); // undefined if(true) { console.log(typeof value); // Uncaught ReferenceError: value is not defined console.log(typeof myConst); // Uncaught ReferenceError: myConst is not defined let value = 'test'; const myConst = 10; console.log(typeof value); // string console.log(typeof myConst); // number } AN INTRODUCTION TO ES6 FEATURES 16
  10. what the hell does ‘let’ mean? let x = 1;

    // let x be 1 // Hey computer, can you please let // this lesson = 'wonderful'; AN INTRODUCTION TO ES6 FEATURES 18
  11. Arrow function - Expression bodies // ES5 var sum =

    function(num1, num2) { return num1 + num2; } // ES6 var sum = (num1, num2) => num1 + num2 ; // ES5 var reflect = function(value) { return value; } // ES6 var reflect = value => value; var getTempItem = function(id) { return { id: id, temp: "Temp" }; } // ES6 var getTempItem = (id) => ({ id: id, name: "temp"}) AN INTRODUCTION TO ES6 FEATURES 20
  12. Arrow function - Lexical this With bind method var PageHandler

    = { init: function() { document.addEventListener('click', (function(event) { console.log(this); // PageHandler this.doSomething(event.type); }).bind(this), false ); }, doSomething: function() { console.log('hi'); } }; ES5 var PageHandler = { init: function() { document.addEventListener('click', function(event) { console.log(this); // #document this.doSomething(event.type); //error }, false ); }, doSomething: function() { console.log('hi'); } }; ES6 var PageHandler = { init: function() { document.addEventListener('click', (event) => { console.log(this); // PageHandler this.doSomething(event.type); }, false ); }, doSomething: function() { console.log('hi'); } }; AN INTRODUCTION TO ES6 FEATURES 21
  13. Default parameters ES6 function makeRequest(url, timeout = 2000, callback =

    function(){}) { }; ES5 function makeRequest(url, timeout, callback) { timeout = timeout || 2000; callback = callback || function() {}; } function makeRequest(url, timeout, callback) { timeout = (typeof timeout !== "undefined") ? timeout : 2000; callback = (typeof callback !== "undefined") ? callback : function(){}; } AN INTRODUCTION TO ES6 FEATURES 22
  14. How default parameter values affect the arguments Object ES5 strict

    mode function mixArgs(first, second) { 'use strict'; first === arguments[0]; second === arguments[1]; first = 'a'; second = 'c'; first !== arguments[0]; second !== arguments[1]; } ES5 non-strict mode function mixArgs(first, second) { first === arguments[0]; second === arguments[1]; first = 'a'; second = 'c'; first === arguments[0]; second === arguments[1]; } ES6 function mixArgs(first, second = "b") { first === arguments[0]; second !== arguments[1]; first = 'a'; second = 'c'; first !== arguments[0]; second !== arguments[1]; } AN INTRODUCTION TO ES6 FEATURES 23
  15. Rest parameters How rest parameters affect the arguments object function

    checkArgs(...args) { args.length === 2; args.length === arguments.length; args[0] === arguments[0]; args[1] === arguments[1]; } checkArgs("a", "b"); function f(x, ...y) { // y is an Array return x * y.length; } f(3, "hello", true) === 6 f.length === 1; Restrictions // Rest parameter must be last formal parameter function checkArgs(first, ...args, last) { } // Setter function argument must not be a rest parameter const obj = { set name(...value) { } } AN INTRODUCTION TO ES6 FEATURES 24
  16. Spread operator ES5 const params = [ 'hello', true, 7

    ]; const other = [ 1, 2, ...params ]; // [ 1, 2, 'hello', true, 7 ] const f = (x, y, ...a) => { return (x + y) * a.length; }; f(1, 2, ...params) === 9; const str = 'foo'; const chars = [ ...str ]; // [ 'f', 'o', 'o' ] ES5 var params = [ 'hello', true, 7 ]; var other = [ 1, 2 ].concat(params); // [ 1, 2, 'hello', true, 7 ] function f (x, y) { var a = Array.prototype.slice.call(arguments, 2); return (x + y) * a.length; }; f.apply(undefined, [ 1, 2 ].concat(params)) === 9; var str = 'foo'; var chars = str.split(''); // [ 'f', 'o', 'o' ] AN INTRODUCTION TO ES6 FEATURES 25
  17. Template string Basic syntax // ES5 var str = 'this

    is a simple string'; var other = "this is an other string"; // ES6 var str = `this is a simple string`; Multiple string // ES5 var str = 'In ES5 this is not legal'; // Uncaught SyntaxError: Invalid or unexpected token // ES6 var str = `In ES6 this is legal`; String interpolation // ES5 var name = 'Stefano', time = 'today'; var str = 'Hello ' + name + ', how are you ' + time + '?'; // ES6 var name = 'Stefano', age = 20; var str = `Hello ${name}, I’m ${age + 14}?`; AN INTRODUCTION TO ES6 FEATURES 27
  18. Enhanced object Computed property names // ES5 var obj =

    { foo: "test" }; obj[prop + getPropName()] = 42; // ES6 var obj = { foo: "test", [prop + getPropName()]: 42 }; Property shorthand // ES5 var obj = { x: x, y: y }; // ES6 var obj = { x, y }; Concise methods // ES5 var person = { toString: function() { } }; // ES6 var person = { toString() { } }; AN INTRODUCTION TO ES6 FEATURES 29
  19. Destructuring Object matching, shorthand notation var obj = getObject(); //

    { a: 1, b: 2, c: 3 }; // ES 5 var a = obj.a; var b = obj.b; var c = obj.c; // ES 6 const { a, b, c } = obj; Array matching and fail-soft // ES 5 var list = [ 1, 2, 3 ]; var a = list[0], b = list[2]; var tmp = a; a = b; b = tmp; // ES 6 const list = [ 1, 2, 3 ]; let [ a, , b ] = list; [ b, a ] = [ a, b ]; Deep matching and assigning to different local variable var obj = getObject(); // { type: 'human', person: { name: 'Jonh' }}; // ES 5 var a = obj.type; var b = obj.person.name; // ES 6 let { type: a, person: { name: b } } = obj; Default parameter and properties order function r({ x, y, w = 10, h = 10 }) { return x + y + w + h; } r({ y:2, x:1 }) === 23 AN INTRODUCTION TO ES6 FEATURES 31
  20. Class definition ES6 class Shape { constructor (id, x, y)

    { this.id = id; this.move(x, y); } move (x, y) { this.x = x; this.y = y; } } ES5 var Shape = function (id, x, y) { this.id = id; this.move(x, y); }; Shape.prototype.move = function (x, y) { this.x = x; this.y = y; }; AN INTRODUCTION TO ES6 FEATURES 33
  21. Class inheritance ES6 class Rectangle extends Shape { constructor (id,

    x, y, width, height) { super(id, x, y); this.width = width; this.height = height; } } ES5 var Rectangle = function (id, x, y, width, height) { Shape.call(this, id, x, y); this.width = width; this.height = height; }; Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; AN INTRODUCTION TO ES6 FEATURES 34
  22. Base class access ES6 class Shape { // other code

    toString () { return `Shape(${this.id})` } } class Rectangle extends Shape { constructor (id, x, y, width, height) { super(id, x, y) // other code } toString () { return "Rectangle > " + super.toString() } } ES5 var Shape = function (id, x, y) { // other code }; Shape.prototype.toString = function (x, y) { return "Shape(" + this.id + ")" }; var Rectangle = function (id, x, y, width, height) { Shape.call(this, id, x, y); // other code }; Rectangle.prototype.toString = function () { return "Rectangle > " + Shape.prototype.toString.call(this); }; AN INTRODUCTION TO ES6 FEATURES 35
  23. Static Members ES6 class Rectangle extends Shape { // other

    code static defaultRectangle () { return new Rectangle("default", 0, 0, 100, 100); } } const defRectangle = Rectangle.defaultRectangle(); ES5 var Rectangle = function (id, x, y, width, height) { // other code }; Rectangle.defaultRectangle = function () { return new Rectangle("default", 0, 0, 100, 100); }; var defRectangle = Rectangle.defaultRectangle(); AN INTRODUCTION TO ES6 FEATURES 36
  24. Getter/Setter ES6 class Rectangle { constructor (width, height) { this._width

    = width this._height = height } set width (width) { this._width = width } get width () { return this._width } set height (height) { this._height = height } get height () { return this._height } get area () { return this._width * this._height } } var r = new Rectangle(50, 20); r.area === 1000; ES5 var Rectangle = function (width, height) { this._width = width; this._height = height; }; Rectangle.prototype = { set width (width) { this._width = width; }, get width () { return this._width; }, set height (height) { this._height = height; }, get height () { return this._height; }, get area () { return this._width * this._height; } }; var r = new Rectangle(50, 20); r.area === 1000; Getter/Setter also directly within classes (and not just within object initializers, as it is possible since ECMAScript 5.1). AN INTRODUCTION TO ES6 FEATURES 37
  25. Class multiple inheritance AN INTRODUCTION TO ES6 FEATURES 38 class

    Developer extends Sentient, ThumbsPrehensile, Person { constructor(){ super(); console.log('Developer'); }
  26. Class multiple inheritance AN INTRODUCTION TO ES6 FEATURES 40 class

    Developer extends Sentient, ThumbsPrehensile, Person { constructor(){ super(); console.log('Developer'); } Invented ES6 syntax
  27. Class multiple inheritance AN INTRODUCTION TO ES6 FEATURES 41 class

    Developer extends Sentient(ThumbsPrehensile(Person)){ constructor(){ super(); console.log('Developer'); } } const developer = new Developer(); // Person // ThumbsPrehensile // Sentient // Developer const Sentient = superclass => class extends superclass { constructor(){ super(); console.log('Sentient'); } } const ThumbsPrehensile = superclass => class extends superclass { constructor(){ super(); console.log('ThumbsPrehensile'); } } class Person { constructor(){ console.log('Person'); } } const thumbsPrehensile = new (ThumbsPrehensile(Object)); thumbsPrehensile.constructor.name === "Object"; const person = new Person(); person.constructor.name === "Person"; ? Not exactly...
  28. What are Modules? • Module code automatically runs in strict

    mode, and there’s no way to opt-out of strict mode. • Variables created in the top level of a module aren’t automatically added to the shared global scope. They exist only within the top-level scope of the module. • The value of this in the top level of a module is undefined. • Modules may import bindings from other modules. AN INTRODUCTION TO ES6 FEATURES 43
  29. Export/Import ES6 // lib/math.js export const sum = (x, y)

    => { return x + y }; export const pi = 3.141593; // someApp.js import * as math from "lib/math"; console.log(`2π = ${math.sum(math.pi, math.pi)}`); // otherApp.js import { sum, pi } from "lib/math"; console.log(`2π = ${sum(pi, pi)}`); ES5 // lib/math.js LibMath = {}; LibMath.sum = function (x, y) { return x + y }; LibMath.pi = 3.141593; // someApp.js var math = LibMath; console.log("2π = " + math.sum(math.pi, math.pi)); // otherApp.js var sum = LibMath.sum, pi = LibMath.pi; console.log("2π = " + sum(pi, pi)); AN INTRODUCTION TO ES6 FEATURES 44
  30. Default & Wildcard ES6 // lib/mathplusplus.js export * from "lib/math";

    export const e = 2.71828182846; export default (x) => Math.exp(x); // someApp.js import exp, { pi, e } from "lib/mathplusplus"; console.log(`e^{π} = ${exp(pi)}`); ES5 // lib/mathplusplus.js LibMathPP = {}; for (symbol in LibMath){ if (LibMath.hasOwnProperty(symbol)) LibMathPP[symbol] = LibMath[symbol]; } LibMathPP.e = 2.71828182846; LibMathPP.exp = function (x) { return Math.exp(x) }; // someApp.js var exp = LibMathPP.exp; var pi = LibMathPP.pi; var e = LibMathPP.e; console.log("e^{π} = " + exp(pi)); AN INTRODUCTION TO ES6 FEATURES 45
  31. • Loading is synchronous. That means if you have multiple

    requires, they are loaded and processed one by one. Node.js require vs. ES6 import/export • You can have dynamic loading where the loaded module name isn't predefined /static, or where you conditionally load a module only if it's "truly required" (depending on certain code flow). AN INTRODUCTION TO ES6 FEATURES 46 require() from NodeJS (CommonJS) • Import can be asynchronous (and in current ES6 Module Loader, it in fact is) and can perform a little better. • You can use named imports to selectively load only the pieces you need. That can save memory. import from ES6
  32. Promise ES6 const msgAfterTimeout = (msg, who, timeout) => {

    return new Promise((resolve, reject) => { setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout) }) }; msgAfterTimeout("", "Foo", 100).then((msg) => msgAfterTimeout(msg, "Bar", 200) ).then((msg) => { console.log(`done after 300ms:${msg}`) }) ES5 function msgAfterTimeout (msg, who, timeout, onDone) { setTimeout(function () { onDone(msg + " Hello " + who + "!"); }, timeout); } msgAfterTimeout("", "Foo", 100, function (msg) { msgAfterTimeout(msg, "Bar", 200, function (msg) { console.log("done after 300ms:" + msg); }); }); AN INTRODUCTION TO ES6 FEATURES 49
  33. Combination const p3 = new Promise((resolve, reject) => { resolve(42);

    }); const p4 = new Promise((resolve, reject) => { reject(43); }); Promise.all([p3, p4]) .catch(function(value) { console.log(Array.isArray(value)) // false console.log(value); // 43 }); ES6 const p1 = new Promise((resolve, reject) => { resolve(42); }); const p2 = new Promise((resolve, reject) => { resolve(43); }); Promise.all([p1, p2]) .then((value) => { console.log(Array.isArray(value)); // true console.log(value[0]); // 42 console.log(value[1]); // 43 }); AN INTRODUCTION TO ES6 FEATURES 50
  34. Symbol type ES6 Symbol('first name') !== Symbol('first name'); const firstName

    = Symbol('first name'); typeof firstName === 'symbol'; const person = {}; person[firstName] = 'Stefano'; 'first name' in person === false; person[firstName] === 'Stefano'; firstName.toString() === 'Symbol(first name)'; ES5 // no equivalent in ES5 Symbol is a primitive, unique and immutable data type to be used as an identifier for object properties. The Symbol function also accepts an optional argument that is the description of the symbol. The description itself cannot be used to access the property, but is used for debugging purposes. AN INTRODUCTION TO ES6 FEATURES 52
  35. Sharing Symbols const uidStrDesc = 'uid'; const uid = Symbol.for(uidStrDesc);

    const object = { [uid]: '12345' }; console.log(object[uid]); // "12345" console.log(uid); // "Symbol(uid)" const uid2 = Symbol.for(uidStrDesc); console.log(uid === uid2); // true console.log(object[uid2]); // "12345" console.log(uid2); // "Symbol(uid)" const uid3 = Symbol(uidStrDesc); console.log(uid === uid3); // false console.log(object[uid3]); // undefined AN INTRODUCTION TO ES6 FEATURES 53
  36. Private Properties ES6 // lib/person.js const firstNameSym = Symbol('first name');

    export default class Person { constructor (firstName) { this[firstNameSym] = firstName; } get firstName () { return this[firstNameSym]; } } ? Not exactly... //test.js import Person from './lib/person.js'; const myFirstName = 'Stefano'; const myPerson = new Person(myFirstName); myPerson.firstName === myFirstName; myPerson['first name'] === undefined; myPerson[Symbol('first name')] === undefined; myPerson[Symbol.for('first name')] === undefined; const symbols = Object.getOwnPropertySymbols(myPerson); console.log(symbols); // [Symbol(first name)] myPerson[symbols[0]] === myFirstName; const mySuperHeroFirstName = 'Clark'; myPerson[symbols[0]] = mySuperHeroFirstName; myPerson[symbols[0]] === mySuperHeroFirstName; Object.getOwnPropertySymbols AN INTRODUCTION TO ES6 FEATURES 54
  37. ES5 collection JavaScript only had one type of collection, represented

    by the Arraytype, for most of its history (though some may argue all non-array objects are just collections of key-value pairs, their intended use was, originally quite different from arrays). Arrays are used in JavaScript just like arrays in other languages, but the lack of other collection options meant arrays were often used as queues and stacks, as well. Since arrays only use numeric indices, developers used non-array objects whenever a non-numeric index was necessary. That technique led to custom implementations of sets and maps using non-array objects. AN INTRODUCTION TO ES6 FEATURES 56
  38. Set & Map A set is a list of values

    that cannot contain duplicates. You typically don’t access individual items in a set like you would items in an array; instead, it’s much more common to just check a set to see if a value is present. A map is a collection of keys that correspond to specific values. As such, each item in a map stores two pieces of data, and values are retrieved by specifying the key to read from. Maps are frequently used as caches, for storing data to be quickly retrieved later. AN INTRODUCTION TO ES6 FEATURES 57
  39. ES5 Map const map = Object.create(null); map.foo = "bar"; //

    retrieving a value const value = map.foo; console.log(value); // "bar" Set const set = Object.create(null); set.foo = true; // checking for existence if (set.foo) { // do something } AN INTRODUCTION TO ES6 FEATURES 58
  40. ES5 Workarounds problems Numeric property const map = Object.create(null); map[5]

    = "foo"; console.log(map["5"]); // "foo" Object property const map = Object.create(null); const key1 = {}; const key2 = { name: 'Stefano '}; map[key1] = "foo"; console.log(map[key2]); // "foo" console.log(map["[object Object]"]); // "foo" Ambiguity issue const set = Object.create(null); set.count = 1; // checking for the existence of "count" or a nonzero value? if (set.count) { // ... } AN INTRODUCTION TO ES6 FEATURES 59
  41. ES6 Set const set = new Set([1, 2, 3, 4,

    5]); set.add(5); // duplicate - this is ignored set.add("5"); console.log(set.size); // 6 const key1 = {}; const key2 = {}; set.add(key1); set.add(key2); console.log(set.size); // 8 console.log(set.has(5)); // true console.log(set.has(6)); // false set.delete(5); console.log(set.has(5)); // false console.log(set.size); // 7 set.clear(); console.log(set.has("5")); // false console.log(set.size); // 0 Memory leak const set = new Set(); let key = { name: 'Mark' }; set.add(key); console.log(set.size); // 1 // eliminate original reference key = null; console.log(set.size); // 1 // get the original reference back with spread operator [...set][0].name === 'Mark'; AN INTRODUCTION TO ES6 FEATURES 60
  42. ES6 Set forEach const set = new Set([1, 2]); set.forEach((value,

    key, ownerSet) => { console.log(`${key} ${value}`); console.log(ownerSet === set); }); // 1 1 // true // 2 2 // true AN INTRODUCTION TO ES6 FEATURES 61
  43. ES6 WeakSet const weakSet = new WeakSet(); let key =

    {}; weakSet.add(key); console.log(weakSet.has(key)); // true weakSet.delete(key); console.log(weakSet.has(key)); // false weakSet.add(1); // Uncaught TypeError: Invalid value used in weak set weakSet.add("a"); // Uncaught TypeError: Invalid value used in weak set weakSet.size === undefined; let key1 = {}; const key2 = {}; const weakSetByIterable = new WeakSet([key1, key2]); console.log(weakSetByIterable.has(key1)); // true console.log(weakSetByIterable.has(key2)); // true key1 = null; // the reference to key1 is no longer accessible AN INTRODUCTION TO ES6 FEATURES 62
  44. ES6 Map const map = new Map([ ["name", "Stefano"], ["age",

    34] ]); map.set("surname", "Sala"); console.log(map.size); // 3 console.log(map.has("age")); // true console.log(map.get("age")); // 34 map.set("age", 20); console.log(map.get("age")); // 20 const key1 = {}, key2 = {}; map.set(key1, 5); map.set(key2, 42); console.log(map.get(key1)); // 5 console.log(map.get(key2)); // 42 map.delete("name"); console.log(map.has("name")); // false console.log(map.get("name")); // undefined console.log(map.size); // 4 Memory leak const map = new Map(); let key = { }; map.set(key, "Mark"); console.log(map.size); // 1 // eliminate original reference key = null; console.log(map.size); // 1 // get the original reference back with spread operator [...map][0][1] === 'Mark'; map.clear(); console.log(map.has("age")); // false console.log(map.size); // 0 AN INTRODUCTION TO ES6 FEATURES 63
  45. ES6 Map forEach const map = new Map([ ["name", "Stefano"],

    ["age", 34] ]); map.forEach((value, key, ownerMap) => { console.log(`${key} ${value}`); console.log(ownerMap === map); }); // name Stefano // true // age 34 // true AN INTRODUCTION TO ES6 FEATURES 64
  46. ES6 WeakMap const weakMap = new WeakMap(); let key =

    {}; weakMap.set(key, 'test'); console.log(weakMap.has(key)); // true weakMap.delete(key); console.log(weakMap.has(key)); // false weakMap.set(1, 'one'); // Uncaught TypeError: Invalid value used as weak map key weakMap.set('a', 123); // Uncaught TypeError: Invalid value used as weak map key weakMap.size === undefined let key1 = {}; const key2 = {}; const weakMapByIterable = new WeakMap([[key1, 'value'], [key2, 123]]); console.log(weakMapByIterable.has(key1)); // true console.log(weakMapByIterable.has(key2)); // true key1 = null; // the reference to key1 is no longer accessible AN INTRODUCTION TO ES6 FEATURES 65
  47. AN INTRODUCTION TO ES6 FEATURES 66 Again the power of

    Object.getOwnPropertySymbols... ...there can be no victory
  48. Private Properties // lib/person.js const weakMap = new WeakMap(); export

    default class Person { constructor (firstName, lastName, address) { weakMap.set(this, { 'firstName': firstName, 'lastName': lastName }); this.address = address; } get firstName () { return weakMap.get(this)['firstName']; } get lastName () { return weakMap.get(this)['lastName']; } } ? not easily but ... yes import Person from './lib/Person'; const myFirstName = 'Stefano'; const myLastName = 'Sala' const age = 34; const myPerson = new Person(myFirstName, myLastName, age); myPerson.firstName === myFirstName; myPerson['firstName'] === undefined; const myUnderCoverName = 'Jarvis'; myPerson.firstName = myUnderCoverName; myPerson.firstName !== myUnderCoverName; AN INTRODUCTION TO ES6 FEATURES 67
  49. Proxying ES6 const myObject = { foo: "Welcome, foo", };

    const handler = { get: (receiver, name) => { console.log(`LOG: access to ${name} property`); return name in receiver ? receiver[name] : new ReferenceError(`"Property ${name} does not exist.`); }, }; const proxy = new Proxy(myObject, handler); proxy.foo === "Welcome, foo"; // LOG: access to foo property proxy.world.toString() === "ReferenceError: \"Property world does not exist." // LOG: access to world property AN INTRODUCTION TO ES6 FEATURES 69
  50. Proxy traps // Object.getPrototypeOf(target), Reflect.getPrototypeOf(target), // target.__proto__, object.isPrototypeOf(target), object instanceof

    target getPrototypeOf: ..., // Object.setPrototypeOf(target), Reflect.setPrototypeOf(target) setPrototypeOf: ..., // for (let i in target) {} enumerate: ..., // Object.keys(target) ownKeys: ..., // Object.preventExtensions(target) preventExtensions: ..., // Object.isExtensible(target) isExtensible :... } var handler = { // target.prop get: ..., // target.prop = value set: ..., // 'prop' in target has: ..., // delete target.prop deleteProperty: ..., // target(...args) apply: ..., // new target(...args) construct: ..., // Object.getOwnPropertyDescriptor(target, 'prop') getOwnPropertyDescriptor: ..., // Object.defineProperty(target, 'prop', descriptor) defineProperty: ..., AN INTRODUCTION TO ES6 FEATURES 70
  51. Reflection ES6 class K { constructor(a, b) { this.c =

    a + b; } } const newInstance = new K(10, 20); newInstance.c === 30; const reflectInstance = Reflect.construct(K, [20, 22]); reflectInstance.c === 42; AN INTRODUCTION TO ES6 FEATURES 71
  52. ECMAScript 6 compatibility table AN INTRODUCTION TO ES6 FEATURES 72

    https://kangax.github.io/compat-table/ es6/
  53. Transpilers Transpilers, or source-to-source compilers, are tools that read source

    code written in one programming language, and produce the equivalent code in another language. AN INTRODUCTION TO ES6 FEATURES 73
  54. BABEL - Learn ES2015 AN INTRODUCTION TO ES6 FEATURES 74

    https://babeljs.io/learn-es2015/#ecmas cript-2015-features-template-strings