ES6
JS evolution
Block scope variables
ES5
var x = 'outer';
function test(inner) {
if (inner) {
var x = 'inner'; // scope whole function
return x;
}
return x; // gets redefined on line 4
}
test(false); // undefined
test(true); // inner
ES6
let x = 'outer';
function test(inner) {
if (inner) {
let x = 'inner';
return x;
}
return x; // gets result from line 1 as expected
}
test(false); // outer
test(true); // inner
ES5
(function(){
var private2 = 1;
})();
console.log(private2); // Uncaught ReferenceError
ES6
{
let private3 = 1;
}
console.log(private3); // Uncaught ReferenceError
IIFE (immediately invoked function expression)
IIFE используется для содержания глобальной среды в чистоте
Достаточно использовать блоки и let
ES6
{
const ARR = [5, 6];
ARR.push(7);
console.log(ARR); // [5,6,7]
ARR = 10; // TypeError
ARR[0] = 3; // значение можно менять
console.log(ARR); // [3,6,7]
}
const
Другой формой объявления переменной с блочной областью видимости является ключевое слово const. Оно предназначено для объявления переменных (констант), значения которых доступны только для чтения. Это означает не то, что значение константы неизменно, а то, что идентификатор переменной не может быть переприсвоен.
О чём стоит помнить:
- Когда дело касается поднятия переменных (hoisting) let и const, их поведение отличается от традиционного поведения var и function. И let и const не существуют до своего объявления
- Областью видимости let и const является ближайший блок.
- В const одновременно с объявлением переменной должно быть присвоено значение.
Стрелочные функции
function Person() {
var self = this;
self.age = 0;
setInterval(function growUp() {
// Коллбэк относится к переменной `self`,
// значением которой является
// ожидаемый объект.
self.age++;
}, 1000);
}
function Person() {
this.age = 0;
setInterval(() => {
this.age++;
// `this` относится к объекту person
}, 1000);
}
var p = new Person();
ES5
ES6
Каждая функция в JavaScript определяет свой собственный контекст this
внутри стрелочных функций значение this то же самое, что и снаружи
var _this = this; // need to hold a reference
$('.btn').click(function(event){
_this.sendData(); // reference outer this
});
$('.input').on('change',function(event){
this.sendData(); // reference outer this
}.bind(this)); // bind to outer this
// this will reference the outer one
$('.btn').click((event) =>
this.sendData());
// implicit returns
const ids = [291, 288, 984];
const messages = ids.map(value =>
`ID is ${value}`);
ES5
ES6
Параметры по умолчанию
let getFinalPrice = (price, tax = 0.7) => price + price * tax;
getFinalPrice(500); // 850, так как значение tax не задано
getFinalPrice(500, 0.2); // 600, значение tax по-умолчанию
// заменяется на 0.2
ES5
function point(x, y, isFlag){
x = x || 0;
y = y || -1;
isFlag = isFlag || true;
console.log(x,y, isFlag);
}
point(0, 0) // 0 -1 true
point(0, 0, false) // 0 -1 true
point(1) // 1 -1 true
point() // 0 -1 true
ES6
function point(x = 0, y = -1, isFlag = true){
console.log(x,y, isFlag);
}
point(0, 0) // 0 0 true
point(0, 0, false) // 0 0 false
point(1) // 1 -1 true
point() // 0 -1 true
Spread / Rest оператор
- ... Oператор называют как spread или rest, в зависимости от того, как и где он используется.
- To escape symbol use backslash \
Spread
function foo(x, y, z) {
console.log(x, y, z);
}
let arr = [1, 2, 3];
foo(...arr); // 1 2 3
Rest
function foo(...args) {
console.log(args);
}
foo(1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]
Расширение возможностей литералов объекта
function getCar(make, model, value) {
return {
// с синтаксисом короткой записи можно пропускать значение свойства, если оно
// совпадает с именем переменной, значение которой мы хотим использовать
make, // аналогично make: make
model, // аналогично model: model
value, // аналогично value: value
// вычисляемые свойства теперь работают в литералах объекта
['make' + make]: true,
// Короткая запись метода объекта пропускает ключевое слово `function` и двоеточие.
// Вместо "depreciate: function() {}" можно написать:
depreciate() {
this.value -= 2500;
}
};
}
let car = getCar('Kia', 'Sorento', 40000);
console.log(car);
// {
// make: 'Kia',
// model:'Sorento',
// value: 40000,
// makeKia: true,
// depreciate: function()
// }
Destructuring Assignment
Text
Получение элемента из массива
ES5
var array = [1, 2, 3, 4];
var first = array[0];
var third = array[2];
console.log(first, third); // 1 3
ES6
const array = [1, 2, 3, 4];
const [first, ,third] = array;
console.log(first, third); // 1 3
Обмен значениями
Text
ES5
var a = 1;
var b = 2;
var tmp = a;
a = b;
b = tmp;
console.log(a, b); // 2 1
ES6
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1
Destructuring Assignment
Text
Деструктуризация нескольких возвращаемых значений
ES5
function margin() {
var left=1, right=2,
top=3, bottom=4;
return {
left: left,
right: right,
top: top,
bottom: bottom
};
}
var data = margin();
var left = data.left;
var bottom = data.bottom;
console.log(left, bottom); // 1 4
ES6
function margin() {
const left=1, right=2,
top=3, bottom=4;
return { left, right, top, bottom };
}
const { left, bottom } = margin();
console.log(left, bottom); // 1 4
С ES6 вызывающий код выбирает только нужные данные
Destructuring Assignment
Text
Деструктуризация и сопоставление параметров
ES5
var user = {
firstName: 'Adrian',
lastName: 'Mejia'};
function getFullName(user) {
var firstName = user.firstName;
var lastName = user.lastName;
return firstName + ' ' + lastName;
}
console.log(getFullName(user));
// Adrian Mejia
ES6
const user = {
firstName: 'Adrian',
lastName: 'Mejia'};
function getFullName({ firstName, lastName }) {
return `${firstName} ${lastName}`;
}
console.log(getFullName(user)); // Adrian Mejia
Destructuring Assignment
Text
Глубокое сопоставление (деструктуризация объекта )
ES5
function settings() {
return { display: { color: 'red' }, keyboard: { layout: 'querty'} };
}
var tmp = settings();
var displayColor = tmp.display.color;
var keyboardLayout = tmp.keyboard.layout;
console.log(displayColor, keyboardLayout);
// red querty
ES6
function settings() {
return { display: { color: 'red' }, keyboard: { layout: 'querty'} };
}
const { display: { color: displayColor }, keyboard: { layout: keyboardLayout }} = settings();
console.log(displayColor, keyboardLayout); // red querty
Destructuring Assignment
Советы:
- Используйте деструктуризацию для получения элементов из массива и для обмена значениями. Не нужно делать временные референсы – сэкономите время.
- Не используйте деструктуризацию массива для нескольких возвращаемых значений, вместо этого используйте деструктуризацию объекта.
Классы и объекты
Text
Каждый объект в JavaScript имеет прототип, который является другим объектом. Все объекты в JavaScript наследуют методы и свойства от своего прототипа.
ES5
var Animal = (function () {
function MyConstructor(name) {
this.name = name;
}
MyConstructor.prototype.speak = function speak() {
console.log(this.name + ' makes a noise.');
};
return MyConstructor;
})();
var animal = new Animal('animal');
animal.speak(); // animal makes a noise.
ES6
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.
Классы и объекты
Text
Советы:
- Всегда используйте синтаксис class и не изменяйте prototype напрямую. Код будет лаконичнее и его будет легче понять.
- Избегайте создания пустого конструктора. У классов есть конструктор по умолчанию если не задать собственный.
О чём стоит помнить:
- Объявления классов не поднимаются наверх (not hoisted). Сначала нужно объявить класс и только после этого использовать его, иначе будет ошибка ReferenceError.
- Нет необходимости использовать ключевое слово function во время задания функций внутри определения класса.
Наследование
Text
ES5
var Lion = (function () {
function MyConstructor(name){
Animal.call(this, name);
}
// prototypal inheritance
MyConstructor.prototype = Object.create(Animal.prototype);
MyConstructor.prototype.constructor = Animal;
MyConstructor.prototype.speak = function speak() {
Animal.prototype.speak.call(this);
console.log(this.name + ' roars ');
};
return MyConstructor;
})();
var lion = new Lion('Simba');
lion.speak(); // Simba makes a noise.
// Simba roars.
ES6
class Lion extends Animal {
speak() {
super.speak();
console.log(this.name + ' roars ');
}
}
const lion = new Lion('Simba');
lion.speak(); // Simba makes a noise.
// Simba roars.
- напрямую вызываем конструкторAnimal с параметрами.
- назначаем прототип Lion прототипом класса Animal.
- вызываем метод speak из родительского класса Animal.
промисы
Text
ES5
function printAfterTimeout(string, timeout, done){
setTimeout(function(){
done(string);
}, timeout);
}
printAfterTimeout('Hello ', 1000, function(result){
console.log(result);
// nested callback
printAfterTimeout(result + 'Reader', 1000, function(result){
console.log(result);
});
});
ES6
function printAfterTimeout(string, timeout){
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve(string);
}, timeout);
});
}
printAfterTimeout('Hello ', 1000).then((result) => {
console.log(result);
return printAfterTimeout(result + 'Reader', 1000);
}).then((result) => {
console.log(result);
});
Генераторы
Text
function *infiniteNumbers() {
var n = 1;
while (true) {
yield n++;
}
}
var numbers = infiniteNumbers(); // возвращает перебираемый объект
numbers.next(); // { value: 1, done: false }
numbers.next(); // { value: 2, done: false }
numbers.next(); // { value: 3, done: false }
Функции-генераторы представляют собой новую особенность ES6, которая позволяет функции создавать много значений в течение некоторого периода времени, возвращая объект (называемый генератором), который может быть итерирован для выброса значений из функции по одному за раз.
Тип данных Symbol
Text
Целью Symbol является создание уникального идентификатора, к которому нельзя получить доступ.
var sym = Symbol("опциональное описание");
console.log(typeof sym); // symbol
var o = {
val: 10,
[Symbol("случайный")]: "Я - символ",
};
console.log(Object.getOwnPropertyNames(o));
// val
использовать new вместе с Symbol(…) нельзя.
Если Symbol используется как свойство/ключ объекта, он сохраняется таким специальным образом, что свойство не будет показано при нормальном перечислении свойств объекта.
Чтобы извлечь символьные свойства объекта, нужно использовать Object.getOwnPropertySymbols(o)
THANKS FOR YOUR ATTENTION
ES6
ES6
By ilyinalada
ES6
- 266