ES2015

Владимир Дашукевич

ES2015 или куда идет Javascript

Владимир Дашукевич

Examples

Where can I try it?

ES2015 is the best practice

Are you ready for pain)

3

2

1

JS everywhere

                [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
            

Blocks

ES5.1: Scope === function

                function(){
                	var a = 2;
                	if (true) {
                		var b = 3;
                	}
                	return a + b;
                }
            

ES6: Scope === {} or () (t)

                function(){
                	let a = 2;
                	if (true) {
                		let b = 3;
                	}
                	return a + b; //???
                }
            
                function(){
                	let a = 2;
                	if (true) {
                		let b = 3;
                	}
                	return a + b; // ReferenceError
                }
            

Loops and arguments (t)

                function(){
                	for (let i = 0; i < 6; i++) {
                		setTimeout(() => { console.log(i) }, 1); // ???
                	}
                }
            
                function(){
                	for (let i = 0; i < 6; i++) {
                		setTimeout(() => { console.log(i) }, 1); // 1, 2, 3, 4, 5
                	}
                }
            

Hoisting

                function(){
                	a; // ???
                	b; // ???
                	var a = 1;
                	var b = 3;
                	var c = a + b;
                }
            
                a;
                b;
                var a = 1;
                var b = 3;
                var c = a + b;
            
                a;
                b;
                var a = 1;
                var b = 3;
                var c = a + b;
            
                a;
                b;
                var a = 1;
                var b = 3;
                var c = a + b;
            
                a;
                b;
                var a = 1;
                var b = 3;
                var c = a + b;
            
                var a;
                var b;
                var c;
                a;
                b;
                a = 1;
                b = 3;
                c = a + b;
            
                a; // undefined
                b; // undefined
                var a = 1;
                var b = 3;
                var c = a + b;
            
                a; // ReferenceError
                b; // ReferenceError
                let a = 1;
                let b = 3;
                let c = a + b;
            

Second declaration (t)

                let a = 1;
                let a = 3; // Error
                var a = 3; // Error
                var b = 3; 
                let b = 3; // Error
            

Const (t)

                const a = 1;
                a = 3; //Error
            
                const a = [1, 2, 3];
                a[1] = "Hello"; // a -> [1, "Hello", 3]
            

Blocks: const === let

Let или var?

Function or =>

                var sum = {
                	sum: 0,
                	add: function(num){
                		this.sum += num;
                	},
                	inc: function(){
                		this.sum++;
                	}
                }
            
                sum.add(5); //sum.sum === 5
                sum.inc(); //sum.sum === 6
                elem.addEventListener("click", sum.inc, false); // Error
                elem.addEventListener("click", sum.inc.bind(sum), false);
            
                var sum = {
                	sum: 0,
                	add: (function(num){
                		this.sum += num;
                	}).bind(sum),
                	inc: (function(){
                		this.sum++;
                	}).bind(sum)
                }
            

=>

                var sum = {
                	sum: 0,
                	add: () => {
                		this.sum += num;
                	},
                	inc: () => {
                		this.sum++;
                	}
                }
            

Где она полезна?

                model.user = {
                	find:function(){ ... },
                	findFirst: function(){ 
                		return new Promise((resolve, reject) => {
                			this.find(...);
                		})
                	}
                }
            
                elem.addEventListener("click", e => {
                	this.doSomething();
                });
            

Везде где вы используете this)))

Test

                (() => this.outerWidth).apply({ outerWidth: 20 }); // ???
                (() => this.outerWidth).bind({ outerWidth: 20 })(); // ???
                (() => arguments[0])(1, 2, 3, 4); // ???
            

Rest parameters

Rest !== arguments

                var foo = function(a, ...rest){
                	rest.forEach(function(a){ 
                		console.log(a)
                	})
                });
            
                foo(1, 2, 3); // 2, 3
                foo(1, 2, 3, 4); // 2, 3, 4
                foo();// 
            

Default Parameter Values

                function foo(x,y) {
                	x = x || 11; 
                	y = y || 31;
                	console.log( x + y );
                };
            

Когда это сработает:

                function foo(x = 11, y = 31) {
                	console.log( x + y );
                };
            

Когда это сработает:

                let a = 10;
                function foo(x = a + 1, y = bar(), z = x + 2) {
                	console.log( x + y );
                };
            
                let a = 10;
                function foo(x = a + 1, y = bar(), z = x + 2) {
                	console.log( x + y );
                };
            
                let a = 10;
                function foo(x = a + 1, y = bar(), z = x + 2) {
                	console.log( x + y );
                };
            
                let a = 10;
                function foo(func = (function(){ return "hello"; })()) {
                	console.log( x + y );
                };
            

Destruction

Destruction

                let [x, y] = [1, 2]
                let [,, y] = [1, 2, 3]
                let {x, y} = foo();
                let {x = 31, y} = foo();
                let {a: x, b: y} = {a: 1, b: 2}
                let {a: {x: X, x: Y}, a } = {a: {x: 1}};
            

source: target

Arguments

                function foo({x: a, y: b}) {
                	console.log( a + b );
                };
            

Promise

                Promise.all([...]).then([users, routes, hotels]) {
                	...
                };
            

От создателей destruction

Spread

                var a = [2,3,4];
                var b = [ 1, ...a, 5 ]; // [1,2,3,4,5]
            

Templates

                let name = "Vladimir"
                let a = `My name is ${ name }`;
            
                let name = "Vladimir"
                let a = `My name 
                			is ${ name }`;
            
                let foo = (strings, ...value) => { ... }
                let a = foo`My name is ${ name }`;
            
                let foo = (strings, ...value) => { ... }
                let a = foo`My name is ${ name }!`;
            
                let foo = (strings, ...value) => { ... }
                let a = foo`My name is ${ name + "'s" }!`;
            

Symbol

                let s = Symbol("Login")
                typeof s === "symbol"
                s.toString(); //Symbol(Login)
                { [s]: "property that can only be assecced through Symbol" }
            
                const s = Symbol.for("Login")
                s === Symbol.for("Login")
                Symbol.keyFor(a) // "Login"
            

Class

Ruby

Class === function

For Java people

                class a { 
                	constructor(){ ... }
                	get prop(){ return "hello" }
                	set prop(val){ ... }
                }
            
                class b extend a { 
                	constructor(){ super(...) }
                }
            
                class b extend a { 
                	constructor(){ new.target }
                }
            

static

                class B {
                	static doWork(){ return "done"; }
                }
            

static нормального человека

                B a = new B();
                a.doWork(); // done
                B.doWork(); // done
            

static в JS

                let a = new B();
                a.doWork(); // ReferenceError
                B.doWork(); // done
            

Classes (t)

                var a = class b{}
                typeof a; // ???
                typeof b; // ???
            

Modules

Old story with new words

                (function(){
                	var a;// private
                	return {
                		doWork: function(){ ... }
                	}
                })();
            
                export {a: 1, foo}
                import {a} as value from "module.js"
            

Положитльые моменты

Как подгружать модули

Collections

Стуктуры данных

Своя стуктура данных

  1. Symbol.iterator
  2. Symbol.toStringTag //toString() -> [object Foo]
  3. Symbol.hasInstance //instanceof
  4. Symbol.species //constructor
  5. Symbol.toPrimitive //operator overload
  6. isConcatSpreadable //[].concat(a, b) -> [1,2,[3,4]]
  7. Symbol.unscopables //with

Promise

Promise

  1. Promise.then
  2. Promise.catch
  3. Promise.resolve
  4. Promise.reject
  5. Promise.all
  6. Promise.race

Promise

  1. Promise.then
  2. Promise.catch
  3. Promise.resolve
  4. Promise.reject
  5. Promise.all
  6. Promise.race

Promise

  1. Promise.then
  2. Promise.catch
  3. Promise.resolve
  4. Promise.reject
  5. Promise.all
  6. Promise.race

Promise (t)

Generators

                var gen = function* count(){
                	for (var x = 0; true; x++) {
                		yield x
                	}
                }
            
                var a = gen()
                a.next(); // => 0
                a.next(); // => 1
                a.next(); // => 2
            
                function* showFeed(){
                	var countries = yield getCountries();
                	renderCountries(countries);
                	var hotels = yield getHotels(countries);
                	renderHotels(hotels);
                	var rooms = yield getRooms(hotels);
                	renderRooms(rooms);
                }
            

Generators (t)

Meta programming

Proxy (t)

Proxy

Зачем это нужно))

  1. Обработка ошибок
  2. Логирование при дебаге
  3. Оптимизация в процессе исполнения

Мелочь

You don't know JS

Questions