Future of JavaScript

at now

Два типа улучшений

  • Значительные фичи
  • Синтаксический сахар

let and const

  • блочная область видимости
  • const - собственно константы
var a = 5;
var b = 10;

if (a === 5) {
  let a = 4;  // Блочная область видимости
  var b = 1;  // Функциональная область видимости
  let c = 42; // Блочная область видимости

  console.log(a);  // 4
  console.log(b);  // 1
  console.log(c);  // 42
} 

console.log(a); // 5
console.log(b); // 1
console.log(c); // ReferenceError: c is not defined

Улучшения записи свойств объектов

  • Сокращённый вариант для foo: foo
  • Вызов из super
  • Вычисляемые свойства
const text = 'Some text';

function getId() {
    return Math.floor(Math.random() * 10) + 1;
}

let obj = {
    text,
    ['prop_' +  getId()]: 'some prop'
}

console.log(obj); // Object {text: "Some text", prop_6: "some prop"}
var obj = {
  toString() {
   return 'Hello ' + super.toString();
  },
}

console.log(obj.toString()) // "Hello [object Object]"

Modules

  • import
  • export
  • System
//double.js
export function double(num) {
    return num * 2;
}

//main.js
import { double } from './double';

console.log(double(2));
// Также есть возможность делать так

//Переименование
import { double as doubleFunc } from './double';


// Реэкспорт
export {double} from './double';
// double.js

export default function double() {}


// main.js

import anyText from './double';

Promise

  • Скажем нет колбэкам.
  • Используются в новых возможностях языка для различных асинхронных операций.
function asyncFunc() {
    return new Promise(
        function(resolve, reject) {
            // Какие-то операции
            resolve(value); // success
            // Или же
            reject(error); // fail
        });
}

asyncFunc()
    .then(function(value) { /* success */ })
    .catch(function(error) { /* fail */ });

Arrow functions

//Было
function(param1, param2) {}
//Стало
(param1, param2) => {};


(param1, param2) => console.log(param1);
param1 => console.log(param1);
var SecretNumbers = {
    multiplicator: 2,
    numbers: [4, 8, 15, 16, 23, 42],
    getAllMultiplicated() {
        var self = this;
        //var multiplicator = this.multiplicator;
        this.numbers.forEach(function(num) {
            console.log(num * self.multiplicator);
        });
    }
}
var SecretNumbers = {
    multiplicator: 2,
    numbers: [4, 8, 15, 16, 23, 42],
    getAllMultiplicated() {
        this.numbers.forEach(num => {
            console.log(num * this.multiplicator);
        });
    }
}
var SecretNumbers = {
    multiplicator: 2,
    numbers: [4, 8, 15, 16, 23, 42],
    getAllMultiplicated() {
        this.numbers.forEach(num => console.log(num * this.multiplicator));
    }
}
//было
function asyncFunc() {
    return new Promise(
        function(resolve, reject) {
            // Какие-то операции
            resolve(value); // success
            // Или же
            reject(error); // fail
        });
}

asyncFunc()
    .then(function(value) { /* success */ })
    .catch(function(error) { /* fail */ });
//стало
function asyncFunc() {
    return new Promise(
        (resolve, reject) => {
            // Какие-то операции
            resolve(value); // success
            // Или же
            reject(error); // fail
        });
}

asyncFunc()
    .then(value => { /* success */ })
    .catch(error => { /* fail */ });

Class

  • Сахар для конструкторов и прототипного наследования
  • Статические методы
  • Конструкторы
  • super()
class Person {
    constructor(name) {
        this.name = name;
    }

    getName() {
        return 'My name is ' + this.name;
    }

    static sayHello() {
        return 'Hello!';
    }
}
class Worker extends Person {
    constructor(name, status) {
        super(name);
        this.status = status;
    }
}
let worker = new Worker('Ivan', 'Some status');

worker.getName(); // 'My name is Ivan'


Person.sayHello(); // 'Hello!'
Worker.sayHello(); // 'Hello!'

Template strings

const firstName = 'Ivan';
const secondName = 'Pertrov';

console.log(firstName + ' ' + secondName);
// 'Ivan Pertrov'

console.log(`${firstName} ${secondName}`);
// 'Ivan Pertrov'

Destructuring

var options = { count: 100, position: 50 };

// До
var count = options.count;
var position = options.position;

// Теперь
var { count, position } = options;
var { count = 10, position = 1 } = options;
function someFunc({ count }) {
   // Some code
}

function someFunc({ count = 10 }) {
   // Some code
}

Обработка параметров

  • default params
  • rest params
  • spread operator
function sumFunc(x, y=12) {
  return x + y;
}
sumFunc(3) == 15
function someFunc2(x, ...z) {
  console.log(z); // ['hello', 'world']
  return x * z.length;
}
someFunc2(3, 'hello', 'world') == 6
function someFunc3(x, y, z) {
  return x + y + z;
}
someFunc3(...[1,2,3]) == 6

for ... of

Обходит значения свойств

// #1
var arr = ['a', 'b', 'c'];
for (var i=0; i<arr.length; i++) {
    // тут вы можете сделать break
    // но выглядит сложно
    var elem = arr[i];
    console.log(elem);
}

// #2
arr.forEach(function (elem) {
    // тут вы не можете сделать break
    console.log(elem);
});


// #3
for (const elem of arr) {
    console.log(elem);
}

Generators

function* idMaker(){
    var index = 0;
    while(true)
        yield index++;
}

var gen = idMaker(); // "Generator { }"

gen.next().value; // 0
gen.next(); // {value: 1, done: false}
gen.next().value; // 2
gen.return(10) // {value: 10, done: true}
gen.next() // {value: undefined, done: true}

Новые структуры данных

  • Map
  • Set
  • WeakMap
  • WeakSet
const map = new Map(); // создание Map
// Может быть также [], Number, String,
// Symbol, function, Boolean
const key = {}; 

map.set(key, 123);

map.get(key) // 123

map.has(key) // true

map.delete(key) // true

map.has(key) // false

Map

const arr = [5, 1, 5, 7, 7, 5];
let set = new Set(arr);

console.log(set) // Set {5, 1, 7}

let obj = {};

set.add(obj);

set.has(obj); // true

Set

const wm = new WeakMap()

wm.set('abc', 123); // TypeError
wm.set({}, 123); // ok

let obj = {a: 2};
wm.set(obj, 2);
wm.get(obj)

WeakMap

  • То же самое, что и map, но
  • ключом может быть только Object
  • слабая связанность
  • нельзя посмотреть всё содержимое

WeakSet

const proxies = new WeakSet();

function createProxy(obj) {
    const proxy = ···;
    proxies.add(proxy);
    return proxy;
}

function isProxy(obj) {
    return proxies.has(obj);
}

Proxy

  • Можно перехватывать базовые операции над объектами
  • или функциями
const target = {};
const handler = {
    get(target, propKey, receiver) {
        console.log('get ' + propKey);
        return 123;
    }
};

const proxy = new Proxy(target, handler);


console.log(proxy.foo);

// get foo
// 123

Symbol

  • Новый примитивный тип
  • Создание уникального ключа
  • Возможность использовать глобальный реестр
const red = Symbol('red');
const red2 = Symbol('red');

red === red2 // false


// Global registry
const red = Symbol.for('red');
const red2 = Symbol.for('red');

red === red2 // true

Symbol.keyFor(red2) // 'red'
const key = Symbol();


let obj = {
  [key]: 'hello'
}

obj[key] // 'hello'
const iterableObject = {
    data: ['one', 'two'],
    [Symbol.iterator]() {
        let index = 0;
        return {
            next: () => {
                if (index < this.data.length) {
                    return { value: this.data[index++] };
                } else {
                    return { done: true };
                }
            }
        };
    }
}
for (const x of iterableObject) {
    console.log(x);
}

// one
// two

Спасибо!

Дмитрий Ермаков

dmitry@ermakov.rocks

ES6

By ermakov

ES6

  • 135