ES2015

2015

История

  • ES5 вышел в 2009

  • В том же году запустили проект "Harmony"

  • ES6 был принят в июне 2015 спустя 6 лет

Зачем?

Новые фичи

Блочная область видимости

let

var data = [1,2,3];
for (let i = 0; i < data.length; i++) {
    console.log(data[i]);
}
console.log(i); // > i is not defined
var data = [1,2,3];
(function(){
    for (var i = 0; i < data.length; i++) {
        console.log(data[i]);
    }
})();

console.log(i); // > i is not defined

const

Object.defineProperty(
    window,
    "PI",
    {
        value:        3.141593,
        enumerable:   true,
        writable:     false,
        configurable: false
    })
PI > 3.0;
const PI = 3.141593;


PI = 10; 
// > Uncaught TypeError: 
     Assignment to constant variable.

Функции

Параметры по умолчанию

function sum(x,y) {
    x = x || 1;
    y = y || 2;
    return x + y;
}

function sum(x = 1, y = 2) {
    return x + y;
}
sum(); // > 3
sum(1,2); // > 3
sum(4); // > 6

Стрелочные функции

let data = [0,1,2,3,4];


data.map(function(i) { return i*2});
// > [0,2,4,6,8]

data.map(i => i*2); 
// > [0,2,4,6,8]

Сохранение контекста

setTimeout(function(){
    console.log(this.name);
}, 100);



setTimeout(() => {
    console.log(this.name);
}, 100);

destructuring

Деструктивное присвоение

var a, b;

[a, b] = [1, 2];
// Зачение по умолчанию )
var [a = 1] = [];
a === 1;

Свитчь переменных :)

var a = 1;
var b = 3;

[a, b] = [b, a];

Пропуск переменных

var a,b;

[a, ,b] = [1,2,3];

Деструкция объектов

var o = {p: 42, q: true};
var {p, q} = o;

console.log(p); // 42
console.log(q); // true 

// Можно задать новые имена переменным
var {p: foo, q: bar} = o;

console.log(foo); // 42
console.log(bar); // true  

Деструкция параметров функции

function log({message = '', type = 'error'}) 
{
  console.log(type, message);
}

log({
    type: 'warn',
    message: 'hello'
})

Object Literals

Object

var obj = {
    // __proto__ - легально
    __proto__: theProtoObj,
    // Сокращение для ‘handler: handler’
    handler,
    // Краткая запись методов
    toString() {
     // вызов метода прототипа
     return "d " + super.toString();
    },
    // вычесление  параметра
    [ 'prop_' + (() => 42)() ]: 42
};

Шаблоные строки

Многострчоные строки

'Я однострочная строка в js ((';
[
    'Текст',
    'Текст',
].join('');

'Текст' +
'Текст';

`А теперь можно
 так.`


`А теперь можно
 так.`

Шаблонизация из коробки

var user = "Павел";
var post = "Директор";
var count = 4;

var msg = `
    Пользователь: ${user}.
    Должность: ${post}
    Количесво: ${count}
`;

Тэгирование строк

var a = 5;
var b = 10;

function tag(strings, ...values) {
  console.log(strings[0]); // "Hello "
  console.log(strings[1]); // " world"
  console.log(values[0]);  // 15
  console.log(values[1]);  // 50

  return "Строка";
}
tag`Hello ${ a + b } world ${ a * b}`;
// > "Строка"

Новые методы

Объединение объектов

var dst  = { quux: 0 };
var src1 = { foo: 1, bar: 2 };
var src2 = { foo: 3, baz: 4 };
Object.assign(dst, src1, src2);
dst.quux === 0;
dst.foo  === 3;
dst.bar  === 2;
dst.baz  === 4;

Объединение объектов ES5

var dst  = { quux: 0 };
var src1 = { foo: 1, bar: 2 };
var src2 = { foo: 3, baz: 4 };
Object.keys(src1).forEach(function(k) {
    dst[k] = src1[k];
});
Object.keys(src2).forEach(function(e) {
    dst[k] = src2[k];
});
dst.quux === 0;
dst.foo  === 3;
dst.bar  === 2;
dst.baz  === 4;

array find

[ 1, 3, 4, 2 ].find(x => x > 3); // 4
[ 1, 3, 4, 2 ].filter(function (x) { return x > 3; })[0]; // 4

String

"foo".repeat(3);

"hello".startsWith("ello", 1); // true
"hello".endsWith("hell", 4);   // true
"hello".includes("ell");       // true
"hello".includes("ell", 2);    // false

Number

Number.isNaN(42) === false;
Number.isNaN(NaN) === true;

Number.isFinite(Infinity) === false;
Number.isFinite(-Infinity) === false;
Number.isFinite(NaN) === false;
Number.isFinite(123) === true;

Number

Number.isSafeInteger(42) === true;
Number.isSafeInteger(9007199254740992) === false;

console.log(0.1 + 0.2 === 0.3); // false
console.log(Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON); // true

console.log(Math.trunc(42.7)) // 42
console.log(Math.trunc( 0.1)) // 0
console.log(Math.trunc(-0.1)) // -0

set

set

let s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
for (let key of s.values())
    console.log(key);

set ES5

var s = {};
s["hello"] = true; s["goodbye"] = true; s["hello"] = true;
Object.keys(s).length === 2;
s["hello"] === true;
for (var key in s)
    if (s.hasOwnProperty(key))
        console.log(s[key]);

set

let mySet = new Set();

var o = {a: 1, b: 2};
mySet.add(o);
mySet.has(o); // true

mySet.add(document.body);
mySet.has(document.querySelector("body")); // true

mySet[0]// не работает

set

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

[v for (v of mySet)]; // [1,2,3,4]
Array.from(mySet); // [1,2,3,4]
[...mySet2]; // [1,2,3,4]

for (let item of mySet) console.log(item);
mySet.forEach((value) => console.log(value));

map

map

let m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) === 34;
m.size === 2;
for (let [ key, val ] of m.entries())
    console.log(key + " = " + val);

map ES5

var m = {};
m["hello"] = 42;
// нету в ES5
// нету в ES5
Object.keys(m).length === 2;
for (key in m) {
    if (m.hasOwnProperty(key)) {
        var val = m[key];
        console.log(key + " = " + val);
    }
}

rest и spread

...

Развертка

function f(x, y, z) { }
var args = [0, 1, 2];
f(...args);

Мерж масивов

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);

Свертка

function test(a,b ...data) {
    console.log(a,b,data);
}

test(1,2,3,4,5);
// > 1,2,[3,4,5]

Классы

Классы в 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;
};

Конструктор

class Shape {
    constructor (id, x, y) {
        this.id = id;
        this.move(x, y);
    }
    move (x, y) {
        this.x = x;
        this.y = y;
    }
}

Наследование

class Rectangle extends Shape {
    constructor (id, x, y, width, height) {
        super(id, x, y);
        this.width  = width;
        this.height = height;
    }
}
class Circle extends Shape {
    constructor (id, x, y, radius) {
        super(id, x, y);
        this.radius = radius;
    }
}

Наследование 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;
var Circle = function (id, x, y, radius) {
    Shape.call(this, id, x, y);
    this.radius = radius;
};
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;

Статические методы

class gameObject {
     move(x,y) {
        ...
    },
    static getWorld() {
        return 'world';
    }
};
gameObject.getWorld();
// > 'world';

Символы

Symbol

Symbol("foo") !== Symbol("foo");
const foo = Symbol();
const bar = Symbol();
typeof foo === "symbol";
typeof bar === "symbol";
let obj = {};
obj[foo] = "foo";
obj[bar] = "bar";
JSON.stringify(obj); // {}
Object.keys(obj); // []
Object.getOwnPropertyNames(obj); // []
Object.getOwnPropertySymbols(obj); // [ foo, bar ]

Symbol

var role = Symbol();
    var user = {
        id: 1001,
        name: 'Administrator',
        [role]: 'admin'
    };

var firstScore = Symbol('score');
var secondScore = Symbol('score');

firstScore === secondScore; // false

Интераторы

и

for of

Интератор

let fibonacci = {
    [Symbol.iterator]() {
        let pre = 0, cur = 1;
        return {
           next () {
               [ pre, cur ] = [ cur, pre + cur ];
               return { done: false, value: cur };
           }
        };
    }
}

for of

for (let n of fibonacci) {
    if (n > 1000)
        break;
    console.log(n);
}

Генераторы

генератор

let fibonacci = function* (numbers) {
    let pre = 0, cur = 1;
    while (numbers-- > 0) {
        [ pre, cur ] = [ cur, pre + cur ];
        yield cur;
    }
};

использование

for (let n of fibonacci(1000))
    console.log(n);

let numbers = [ ...fibonacci(1000) ];

let [ n1, n2, n3, ...others ] = fibonacci(1000);

Promises

Promises

function 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}`);
});

Promises

Promise.all([
    fetchPromised("http://backend/foo.txt", 500),
    fetchPromised("http://backend/bar.txt", 500),
    fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
    let [ foo, bar, baz ] = data;
    console.log(`success: foo=${foo} bar=${bar} baz=${baz}`);
}, (err) => {
    console.log(`error: ${err}`);
});

Proxying

Proxying

let target = {
    foo: "Welcome, foo"
};
let proxy = new Proxy(target, {
    get (receiver, name) {
        return name in receiver ? receiver[name] : `Hello, ${name}`;
    }
});
proxy.foo   === "Welcome, foo";
proxy.world === "Hello, world";

Модули

export

export myFunction;
export const foo = Math.sqrt(2);

export default myFunctionOrClass;

export

export var x = 42;               
export function foo() {};        

export default 42;                 
export default function foo() {};   

export { encrypt };              
export { decrypt as dec };       
export { encrypt as en } from 'crypto'; 
export * from 'crypto';                 

import

import 'jquery';             
import $ from 'jquery';           
import { $ } from 'jquery';         
import { $ as jQuery } from 'jquery'; 

import * as crypto from 'crypto';

транспайлер – переписывающий код на ES-2015

ES2015

Всем спасибо!

Андреев Сергей

 US

Ведущий front-end разработчи

Made with Slides.com