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