Преобразует код из ES-2015 в ES5
ES5 поддерживается везде
Легко добавляется в состав системы сборки frontend'a (Gulp, Grunt, Webpack ...)
Область видимости переменной let — блок {}
function showApplesCount() {
var apples = 5;
if (true) {
var apples = 10;
alert(apples); // 10
}
alert(apples); // 10
}
function showApplesCount() {
let apples = 5; // (*)
if (true) {
let apples = 10;
alert(apples); // 10
}
alert(apples); // 5
}
let видна только после объявления
alert(a); // undefined
var a = 5;
alert(a); // ReferenceError
let a = 5;
for(var i=0; i<10; i++) {
/* … */
}
alert(i); // 10
for(let i=0; i<10; i++) {
/* … */
}
alert(i); // i is not defined
Задаёт константу, которую нельзя менять
const apple = 5;
apple = 10; // ошибка
Особый синтаксис присваивания, при котором можно присвоить массив или объект сразу нескольким переменным, разбив его на части
var coord = [150, 200];
var x = coord[0];
var y = coord[1];
alert(x); // 150
alert(y); // 200
let [x, y] = [150, 200];
alert(x); // 150
alert(y); // 200
let [first, last, ...rest] = "Юлий Цезарь Император Рима".split(" ")
alert(first); // Юлий
alert(last); // Цезарь
alert(rest); // ["Император", "Рима"]
let [first='First', last] = [];
alert(first); // First
alert(last); // undefined
let {var1, var2} = {var1:…, var2:…}
let options = {
title: "Меню",
width: 100,
height: 200
};
let {title, width = 0, height:h} = options;
alert(title); // Меню
alert(width); // 100
alert(h); // 200
var value = 'value';
var str = 'some string with ' + value + ' and ' +
'multiline'
Обратные кавычки ``
alert(`моя
многострочная
строка`);
let apples = 2;
let oranges = 3;
alert(`Sum of: ${apples} + ${oranges} = ${apples + oranges}`);
// Sum of 2 + 3 = 5
Параметры по умолчанию
function func(title = "Title", width = getWidth(), height = 200) {
alert(`${title} ${width} ${height}`);
}
func("Меню"); // Меню 100 200
Оператор spread вместо arguments
function showName(firstName, lastName, ...rest) {
alert(`${firstName} ${lastName} - ${rest}`);
}
showName("Юлий", "Цезарь", "Император", "Рима");
// Юлий Цезарь - Император,Рима
Деструктуризация в параметрах
let options = {
title: "Меню",
width: 100,
height: 200
};
function showMenu({title, width, height}) {
alert(`${title} ${width} ${height}`); // Меню 100 200
}
showMenu(options);
Свойство name
function f() {}
f.name === "f" // true
Стрелочный синтаксис
var positive = numbers.filter(function(num) {
return num > 0
});
var positive = numbers.filter(num => num > 0);
Короткое свойство
let name = "Вася";
let isAdmin = true;
let user = {
name,
isAdmin
};
alert( JSON.stringify(user) );
// {"name": "Вася", "isAdmin": true}
Вычисляемые свойства
let propName = "firstName";
let user = {
[propName]: "Вася"
};
Методы объекта
let name = "Вася";
let user = {
name,
// вместо "sayHi: function()
sayHi() {
alert(this.name);
}
};
user.sayHi(); // Вася
__proto__ и super
let animal = {
walk() {
alert("I'm walking");
}
};
let rabbit = {
__proto__: animal,
walk() {
super.walk(); // I'm walking
}
};
rabbit.walk();
Синтаксис
class Название [extends Родитель] {
constructor
методы
}
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
let user = new User("Вася");
user.sayHi(); // Вася
Геттеры и сеттеры
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
set fullName(newValue) {
[this.firstName, this.lastName] = newValue.split(' ');
}
}
let user = new User("Вася", "Пупкин");
alert( user.fullName ); // Вася Пупков
user.fullName = "Иван Петров";
alert( user.fullName ); // Иван Петров
Статические свойства
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
static createGuest() {
return new User("Гость", "Сайта");
}
};
let user = User.createGuest();
Наследование
class Animal {
constructor(name) {
this.name = name;
}
walk() {
alert(`${this.name} walk`);
}
}
class Rabbit extends Animal {
walk() {
super.walk();
alert("...and jump!");
}
}
new Rabbit("Вася").walk();
private и protected свойства
Ключевое слово export можно ставить:
export let one = 1;
let one = 1;
let two = 2;
export {one as once, two as twice};
import {one, two} from "./nums";
Object. Ключ - только строка
Map. Ключ - произвольный тип
let map = new Map([
['string', 'str1'],
[1, 'num1']
]);
map.set(true, 'bool1');
map.size() // 3
Для итерации используются:
let recipeMap = new Map([
['огурцы', '500 гр'],
['помидоры', '300гр'],
]);
for(let key of recipeMap.keys()) {
alert(key); // огурцы, помидоры
}
for(let amount of recipeMap.values()) {
alert(amount); // 500 гр, 350 гр
}
for(let entry of recipeMap)
alert(entry); // ['огурцы', '500 гр'] ...
}
Коллекция множества уникальных значений
let set = new Set();
let vasya = {name: "Вася"};
let petya = {name: "Петя"};
let dasha = {name: "Даша"};
set.add(vasya);
set.add(petya);
set.add(dasha);
set.add(vasya);
set.add(petya);
alert( set.size ); // 3
set.forEach( user => alert(user.name ) ); // Вася, Петя, Даша
Ограничения:
let activeUsers = [
{name: "Vasia"},
{name: "Petia"},
{name: "Masha"}
];
let weakMap = new WeakMap();
weakMap.set(activeUsers[0], 1);
weakMap.set(activeUsers[1], 2);
weakMap.set(activeUsers[2], 3);
alert( weakMap.get(activeUsers[0]) ); // 1
activeUsers.splice(0, 1); // в weakMap теперь только 2 элемента
activeUsers.splice(0, 1); // в weakMap теперь только 1 элемент
20 лет назад
for (var index = 0; index < myArray.length; index++) {
console.log(myArray[index]);
}
ES5
myArray.forEach(function (value) {
console.log(value);
});
for (var index in myArray) { // bad
console.log(myArray[index]);
}
ES6
for (var value of myArray) {
console.log(value);
}
Плюсы
Callback-hell
Синтаксис
var promise = new Promise(function(resolve, reject) {
// В ней можно делать любые асинхронные операции,
// А когда они завершатся — нужно вызвать одно из:
// resolve(результат) при успешном выполнении
// reject(ошибка) при ошибке
})
promise.then(onFulfilled, onRejected)
Пример
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("result"), 1000);
});
promise.then(
result => {
alert("Fulfilled: " + result); // result - аргумент resolve
},
error => {
alert("Rejected: " + error); // error - аргумент reject
}
);
Цепочки
httpGet('/article/promise/user.json')
// 1. Получить данные о пользователе в JSON и передать дальше
.then(response => {
let user = JSON.parse(response);
return user;
})
// 2. Получить информацию с github
.then(user => {
return httpGet(`https://api.github.com/users/${user.name}`);
})
// 3. Вывести аватар
.then(githubUser => {
githubUser = JSON.parse(githubUser);
let img = new Image();
img.src = githubUser.avatar_url;
document.body.appendChild(img);
})
.catch(error => {
alert(error);
});
Новый вид функций.
Могут приостанавливать своё выполнение, возвращать промежуточный результат и далее возобновлять его позже, в произвольный момент времени
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
let generator = generateSequence();
let one = generator.next(); // {value: 1, done: false}
let two = generator.next(); // {value: 2, done: false}
let three = generator.next(); // {value: 3, done: true}
Пример: Написание "плоского" асинхронного кода.
Пример: Написание "плоского" асинхронного кода.
function* showUserAvatar() {
let user = yield fetch('/article/generator/user.json');
let githubUser = yield fetch(`https://api.github.com/users/${user.name}`)
return githubUser.avatar_url;
}
function execute(generator, yieldValue, callback) {
let next = generator.next(yieldValue);
if (!next.done) {
next.value.then(
result => execute(generator, result, callback),
err => generator.throw(err)
);
} else {
callback(next.value);
}
}
execute( showUserAvatar(), null, callback );