Materials:
CodeDojo. Основы ES6 (Youtube)
Обзор базовых возможностей ES6 (Habrahabr)
- let
- const
- Spread operator
- Template strings
- Multi-line strings
- Function parameters
- for...of
- Arrow functions
- Destructuring Assignment
- Objects
- Classes
- Promises
- Symbols
- Iterators
- Generators
let ↑
const ↑
Spread operator (оператор разворота) ↑
Convert array into its separate values
functionName(...array);
let arrayCopyES6 = [...array];
let concatenatedArray = [...array1, ...array2, ...array3]
or
var arrayCopy = [].concat(array); // ES5 way
ES5
Math.max.apply(Math, [2, 100, 1, 6, 43]) // 100
ES6
Math.max(...[2, 100, 1, 6, 43]) // 100
Template strings (literals) ↑
Template literals are enclosed by the back-tick ` `
Consider name
is variable
`Hello ${name}`
You can make calculations inside template string
`${parseInt(x) + parseInt(y)}`
Multi-line strings ↑
Use back-tick ``
for multi-line strings instead of concatenation '\n' + ''
const template6 =
`<li>
<div class="view">
<label></label>
</div>
<input class="edit" value="">
</li>`;
Function parameters ↑
Set default values
function greet(greeting = 'Hello', name = 'friend') {
...
}
Iterate throught parameters
function sum(...values) {
let sum = 0;
values.forEach(function(value) {
sum += value;
});
or
values.reduce(function(prevValue, currentValue) {
return prevValue + currentValue;
});
}
for...of ↑
let array = ['one', 'two', 'three'];
array.foo = 'hello';
for (let i in array) {
console.log(i); // prints '0', '1', '2', 'foo'
}
for (let i of array) {
console.log(i); // prints 'one', 'two', 'three'
}
Arrow functions ↑
Стрелка должна идти сразу после параметров, на той же строке.
let add = (x, y) => x + y;
let square = x => x * x;
let answer = () => 42;
let multiply = (x, y) => {
let result = x * y;
return result;
};
let getPerson = () => ({
name: 'John'
});
(() => console.log('IIFE'))();
- В стрелочной функции значение this береться из контекста (i.e. window for setTimeout())
- Нельзя использовать как конструкторы объектов
let Task = () => console.log('Creating task');
let task = new Task();
> Uncaught TypeError: Task is not a constructor
- Нельзя использовать методы
bind()
,call()
,apply()
Стрелочные ф-ции полезны:
- анономные ф-ции
- методы класса
Destructuring Assignment (Деструктивное присваивание) ↑
Array destructing ↑
let languages = ['JS', 'PHP', 'Python', 'Ruby'];
let [js, php, py, rb] = languages;
or
let [js, php, py, rb] = ['JS', 'PHP', 'Python', 'Ruby'];
let scores = [3, 4, 5];
let [low, , high] = scores;
> 3 5
let scores = [3, 4, 5, 6, 7];
let [low, , high, ...rest] = scores;
console.log(low, high, rest);
> 3 5 [6, 7]
let scores = [3, 4, 7];
let [low, mid, high = 5, upper = 9] = scores;
> 3 4 7 9
let scores = [3, 4, [5, 6]];
let [low, mid, high] = scores;
console.log(low, mid, high);
> 3 4 [5, 6]
Вытащить значения из сложенного массива:
let scores = [3, 4, [5, 6]];
let [low, mid, [high, higher]] = scores;
console.log(low, mid, high, higher);
> 3 4 5 6
function computeScore([low, mid]) {
console.log(low, mid);
}
computeScore([3, 4]);
> 3 4
function getScores() {
return [3, 4, 5];
}
let [rLow, rMid, rHigh] = getScores();
console.log(rLow, rMid, rHigh);
> 3 4
let yes = 'Yes';
let no = 'No';
[yes, no] = [no, yes];
Object destructing ↑
let person = {
firstName: 'John',
lastName: 'Doe'
};
let {firstName, lastName, age = 25} = person;
Имена переменных должны совпадать с именами свойств объекта. Иначе:
let {firstName: first, lastName: last} = person;
function getUserInfo() {
return {
firstName: 'John',
lastName: 'Doe',
social: {
facebook: 'johndoe',
twitter: 'jdoe'
}
};
}
let {firstName: fname, lastName: lname, social: { twitter } } = getUserInfo();
console.log(fname, lname, twitter);
> John Doe jdoe
Object spread only includes own, enumerable properties. That means you lose methods when you spread instances of an object.
Objects ↑
Если названия свойств совпадают с названиями переменных - можно указать только свойства.
let firstName = 'Bill',
lastName = 'Gates';
let person = {
firstName,
lastName,
sayHello() {
console.log(`Hi! My name is ${firstName} ${lastName}`);
}
};
console.log(person);
person.sayHello();
Object {firstName: "Bill", lastName: "Gates"} Hi! My name is Bill Gates
Classes ↑
- Классы не попадают в глобальное пространство имен (window в браузере).
- Классы не всплывают (hoisting).
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
const animal = new Animal('animal');
animal.speak(); // animal makes a noise.
- Class declaration
class Clazz { ... }
- Class expression
let Clazz = class Clazz { ... }
- +inheritance
let SubClazz = class extends Clazz { ... }
Inheritance ↑
class Task {
constructor(param) {
...
}
method() {
...
}
}
class SubTask extends Task {
constructor(param) {
super(param);
...
}
method() {
super.method();
...
}
}
Promises ↑
Function returning promise:
function applyForVisa(document) {
let promise = new Promise(function (resolve, reject) {
condition
? resolve()
: reject();
});
return promise;
}
Or another way:
return Promise.resolve();
return Promise.reject();
Promise result
applyForVisa(document)
.then(bookHotel)
.catch(error => console.error(error));
Дождаться выполнения всех промисов
Promise.all([promise1, promise2, promise3])
.then()
.catch();
Дождаться выполнения первого промиса
Promise.race([promise1, promise2, promise3])
.then()
.catch();
Symbols ↑
Declare:
let symbol = Symbol('name');
First search for existing:
let symbol = Symbol.for('name')
Equality
let symbol1 = Symbol('name');
let symbol2 = Symbol('name');
console.log(symbol1 === symbol2);
> false
let symbolf1 = Symbol.for('namy');
let symbolf2 = Symbol.for('namy');
console.log(symbolf1 === symbolf2);
> true
let name = Symbol.keyFor(symbolf1);
console.log(name);
> namy
As object property
let user = {
username: 'R2D2',
[Symbol.for('password')]: 'c3po'
};
console.log(user[Symbol.for('password')]);
> c3po
New Object method
Object.getOwnPropertySymbols(user);
Iterators ↑
let array = ['item1', 'item2', 'item3'];
let iterator = array[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
> Object {value: "item1", done: false}
Object {value: "item2", done: false}
Object {value: "item3", done: false}
Object {value: undefined, done: true}
Iterate all available objects:
let next = iterator.next();
while (!next.done) {
console.log(next.value);
next = iterator.next();
}
Result is the same as while using for...of
> item1
item2
item3
Should return object with method next()
which returns object containing value: any
and done:boolean
.
let myIterator = {
[Symbol.iterator]() {
return {
next() {
return {
value: undefined,
done: true
};
}
};
}
};
Literature:
[habr] Итерируемые объекты и итераторы
Generators ↑
function* generator() { ... }
or
function * generator() { ... }
or
function *generator() { ... }
or
let generator = function*() { ... }
let obj = {
*generator() { ... }
}
class Clazz {
*generator() { ... }
}
Stop function and return any value:
yield value;
let iterator = generator();
iterator.next()
Value can be sent:
iterator.next([value])
function* genny() {
let result = 1 + (yield);
console.log(`Result: ${result}`);
}
iter = genny();
console.log(iter.next());
console.log(iter.next(1));
> Object {value: undefined, done: false}
Result: 2
Object {value: undefined, done: true}
Get value:
iterator.next().value
Stop generator:
iterator.return()
Throw an error:
iterator.throw(new Error('Error'))
Can be processed in generator
function* generator() {
try {
yield 1;
yield 2;
yield 3;
} catch (e) {
console.error(e);
}
}