es2015+: давно пора!
TRANSCRIPT
ES2015+
Давно пора!
Ярослав Савченко
Про ES
Почему ECMA?
Ecma International - организация, которая занимается стандартизацией
информационных и коммуникационных технологий.
ECMAScript - стандарт, основа для создания скриптовых языков.
Таких как: JScript, ActionScript, JavaScript (браузеры, NodeJS, ...)
Немного скучной истории
1995 - Появление JavaScript
1997 - ES1
1998 - ES2, минорные правки
1999 - ES3
2008 - ES4 (так и не вышел)
2009 - ES5
2015 - ES2015
Что сейчас со стандартом
Ежегодные релизы
Фичи проходят несколько стадий:
● Stage 0 Proposals
● Active Proposals (stage 1-3)
● Finished Proposals
● Inactive Proposals
Готовые фичи входят в стандарт
Браузеры не успевают. Некоторые разработчики тоже :)
Некоторые фичи
1. let & const - замена var
Область видимости - блок {} (if, for, etc.), а не функция
let a = 5;
if (true) {
let a = 10;
console.log(a); // 10 внутри блока}
console.log(a); // 5 снаружи блока
var a = 5;
if (true) {
var a = 10;
console.log(a); // 10 внутри блока}
console.log(a); // 10 снаружи блока
1. let & const - замена var
Нет всплытия (hoisting)
console.log(a); // error!
let a = 5;
console.log(a); // undefined
var a = 5;
1. let & const - замена var
Константы
const a = 42;
a = 0; // error!
const a = {
value: 0
}
a.value = 42; // ok
a = 'new value'; // error!
2. Литералы объектов
Свойства
let eventName = 'miniq';
let city = 'Vitebsk';
let conference = {
eventName,
city,
getCity() {
return this.city;
}
};
//эквивалентно
eventName: eventName,
city: city,
getCity: function() {
return this.city;
}
2. Литералы объектов
Свойства
let eventName = 'miniq';
let city = 'Vitebsk';
let conference = {
eventName,
city,
getCity() {
return this.city;
}
};
//эквивалентно
eventName: eventName,
city: city,
getCity: function() {
return this.city;
}
2. Литералы объектов
[вычисляемые имена свойств]
let eventName = 'miniq';
let city = 'Vitebsk';
let conference = {
eventName,
city,
[city + '-17']: guestsCount,
getCity() {
return this.city;
}
};
conference[city + '-17'] = guestsCount;
2. Литералы объектов
Ссылка на прототип __proto__
let eventName = 'miniq';
let city = 'Vitebsk';
let conference = {
__proto__: Event,
eventName,
city,
[city + '-17']: guestsCount,
getCity() {
return this.city;
}
};
2. Литералы объектов
Доступ к родительским свойствам через super
let eventName = 'miniq';
let city = 'Vitebsk';
let conference = {
__proto__: Event,
eventName,
city,
[city + '-17']: guestsCount,
getCity() {
return this.city;
},
registerAttendee() {
super.registerPerson();
}
};
‘Event.prototype.registerPerson’
в контексте conference
3. Деструктурирующее присваивание
Объекты
$.get( '/miniq/2017', ( response ) => {
{time, date, guestsCount} = response;
//...
});
$.get( '/miniq/2017', ( response ) => {
{guestsCount, ...dateAndTime} = response;
//...
});
dateAndTime = { date: '23.03.2017', time: '19:00'}
{
guestsCount: 9001,
date: '23.03.2017',
time: '19:00'
}
3. Деструктурирующее присваивание
Объекты, rest-параметры
$.get( '/miniq/2017', ( response ) => {
{time, date, guestsCount} = response;
//...
});
$.get( '/miniq/2017', ( response ) => {
{guestsCount, ...dateAndTime} = response;
//...
});
dateAndTime = { date: '23.03.2017', time: '19:00'}
{
guestsCount: 9001,
date: '23.03.2017',
time: '19:00'
}
3. Деструктурирующее присваивание
Объекты, деструктурирование объекта-параметра
$.get( '/miniq/2017', ( {guestsCount, date, time} ) => {
//...
});
$.get( '/miniq/2017', ( {guestsCount, ...dateAndTime} ) => { //...});
3. Деструктурирующее присваивание
Массивы
let miniq = ['Tech debt', 'ES2015+', 'Competitions', 'coffee', 'good mood'];
function showInfo([firstTheme, secondTheme, thirdTheme, ...rest]) {
console.log(secondTheme);
console.log(rest.join(','));
}
showInfo(miniq);
// ES2015+
// coffee,good mood
3. Деструктурирующее присваивание
Массивы
let miniq = ['Tech debt', 'ES2015+', 'Competitions', 'coffee', 'good mood'];
function showInfo([firstTheme, secondTheme, thirdTheme, ...rest]) {
console.log(secondTheme);
console.log(rest.join(','));
}
showInfo(miniq);
// ES2015+
// coffee,good mood
4. Строки
Строки-шаблоныlet attendee = 'Ivan';
function getNextNumber(){/*...*/};
console.log(`Hi, ${attendee}! Your number is ${getNextNumber()}!`);
Многострочные литералыlet multiline = 'Yes,
now it’s
possible';
` - это backtick, он живет на кнопке “ё” и помогает делать:
4. Строки
Строки-шаблоныlet attendee = 'Ivan';
function getNextNumber(){/*...*/};
console.log(`Hi, ${attendee}! Your number is ${getNextNumber()}!`);
Многострочные строкиlet multiline = 'Yes,
now it’s
possible';
` - это backtick, он живет на кнопке “ё” и помогает делать:
5. Стрелочные функции
function() {}
() => {}
5. Стрелочные функции
Сохранение контекста
let miniq = {
greeting: 'Hi there',
startTimer: function() {
setTimeout(function() {
console.log(this.greeting); //this === window
}, time);
}
}
let miniq = {
greeting: 'Hi there',
startTimer: () => {
setTimeout(() => {
console.log(this.greeting); //this === miniq. Прощай, self = this! }, time);
}
}
5. Стрелочные функции
Autoreturn
[1, 2, 3].map( n => n+1 );
6. Параметры по-умолчанию
function getHeadline(title, date, place){
title = title || 'Miniq';
date = date || '23.03.2017';
place = place || 'Vitebsk';
console.log(`${title}, ${date} in ${place}`);
}
function getHeadline(title = 'Miniq', date = '23.03.2017', place = 'Vitebsk'){
console.log(`${title}, ${date} in ${place}`);
}
7. Классы
Как было:
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function() {
return `(${this.x}, ${this.y})`;
}
7. Классы
Как наследовались:
function Point(x, y) {...}
function ColorPoint(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
}
ColorPoint.prototype = Object.create(Point.prototype);
ColorPoint.prototype.constructor = ColorPoint;
ColorPoint.prototype.toStringWithColor = function() {
return `(${this.x}, ${this.y}) -
${this.color}`;
}
7. Классы
Как стало:
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `(${this.x}, ${this.y})`;
}
static get hello() {
return 'Hi, I\'m a point!'
}
}
7. Классы
Наследование:
class Point {...}
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y);
this.color = color;
}
toString() {
return super.toString() +
` - ${this.color}`;
}
}
7. Классы
Наследование:
class Point {...}
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y);
this.color = color;
}
toString() {
return super.toString() +
` - ${this.color}`;
}
}
8. Модули
Как было без модулей?
● Проблемы с порядком загрузки
● “Сшивание” файлов
● Общая область видимости
● Все в одной куче
Плохо, короче.
8. Модули
“Стройка встала, на стройке паралич:
Прораб изобретает свой собственный кирпич”
● Module pattern
● AMD (RequireJS)
● CommonJS
● UMD
8. Модули
Стандартное решение: import & export
// event-utility.js
const config = {/*...*/}
export function sendInvitation(person) {/*...*/}
export function registerSomeone(person) {/*...*/}
8. Модули
// event-utility.js
const config = {/*...*/}
export function sendInvitation(person) {/*...*/}
export function registerSomeone(person) {/*...*/}
// miniq-app.js
// импорт одной из функцийimport {sendInvitation} from './event-utility';
// импорт функции в переменную с другим именемimport {registerSomeone as register} from './event-utility';
// импорт всего содержимого в объектimport * as util from './event-utility';
// ...
export class MiniqApp {/*...*/}
8. Модули
// event-utility.js
const config = {/*...*/}
export function sendInvitation(person) {/*...*/}
export function registerSomeone(person) {/*...*/}
// miniq-app.js
// импорт одной из функцийimport {sendInvitation} from './event-utility';
// импорт функции в переменную с другим именемimport {registerSomeone as register} from './event-utility';
// импорт всего содержимого в объектimport * as util from './event-utility';
// ...
export class MiniqApp {/*...*/}
8. Модули
// event-utility.js
const config = {/*...*/}
export function sendInvitation(person) {/*...*/}
export function registerSomeone(person) {/*...*/}
// miniq-app.js
// импорт одной из функцийimport {sendInvitation} from './event-utility';
// импорт функции в переменную с другим именемimport {registerSomeone as register} from './event-utility';
// импорт всего содержимого в объектimport * as util from './event-utility';
// ...
export class MiniqApp {/*...*/}
8. Модули
// event-utility.js
const config = {/*...*/}
export function sendInvitation(person) {/*...*/}
export function registerSomeone(person) {/*...*/}
// miniq-app.js
// импорт одной из функцийimport {sendInvitation} from './event-utility';
// импорт функции в переменную с другим именемimport {registerSomeone as register} from './event-utility';
// импорт всего содержимого в объектimport * as util from './event-utility';
// ...
export class MiniqApp {/*...*/}
8. Модули
// miniq-app.js
import {sendInvitation} from './event-utility';
import {sendInvitation as invite} from './event-utility';
import * as util from './event-utility';
// ...
export class MiniqApp {/*...*/}
// app.js
import {MiniqApp} from './miniq-app';
8. Модули
// miniq-app.js
import {sendInvitation} from './event-utility';
import {sendInvitation as invite} from './event-utility';
import * as util from './event-utility';
// ...
export default class MiniqApp {/*...*/}
// app.js
import Miniq from './miniq-app';
И это еще не все!..
● Promises
● Set, Map, Weakset & Weakmap
● Итераторы, for … of
● Генераторы
● async/await
● Symbol
● Proxie
● Unicode
● ...
И как этим воспользоваться?
Часть уже есть в браузерах.
https://kangax.github.io/compat-table/es6/
И как этим воспользоваться?
Для модулей понадобится сборщик / загрузчик:
● Webpack (мощный, но требует Webpack Ops)
● Rollup (попроще)
● SystemJS
Для остального - транспайлеры
● Babel (остальные не нужны)
● Traceur
И как этим воспользоваться?
Babel
Как часть процесса сборки:
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
И как этим воспользоваться?
Babel
В консоли:
babel script.js --out-file script-compiled.js
Или прямо на странице:
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
Зачем все это?
Плюсы:
● Улучшают читаемость
● Упрощают некоторые задачи
● Делают прежде неясные моменты более четкими
Минусы:
● Непривычно
● Усложнение процесса сборки
We need to go deeper!
ES6 in Depth:
https://ponyfoo.com/articles/tagged/es6-in-depth
Современные возможности ES-2015:
https://learn.javascript.ru/es-modern
Таблицы поддержки новых возможностейhttps://kangax.github.io/compat-table/es6/
http://node.green/
Спасибо за внимание!Вопросы?