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/
Спасибо за внимание!
Вопросы?

ES2015+: давно пора!

  • 1.
  • 2.
    Про ES Почему ECMA? EcmaInternational - организация, которая занимается стандартизацией информационных и коммуникационных технологий. ECMAScript - стандарт, основа для создания скриптовых языков. Таких как: JScript, ActionScript, JavaScript (браузеры, NodeJS, ...)
  • 3.
    Немного скучной истории 1995- Появление JavaScript 1997 - ES1 1998 - ES2, минорные правки 1999 - ES3 2008 - ES4 (так и не вышел) 2009 - ES5 2015 - ES2015
  • 4.
    Что сейчас состандартом Ежегодные релизы Фичи проходят несколько стадий: ● Stage 0 Proposals ● Active Proposals (stage 1-3) ● Finished Proposals ● Inactive Proposals Готовые фичи входят в стандарт Браузеры не успевают. Некоторые разработчики тоже :)
  • 5.
  • 6.
    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 снаружи блока
  • 7.
    1. let &const - замена var Нет всплытия (hoisting) console.log(a); // error! let a = 5; console.log(a); // undefined var a = 5;
  • 8.
    1. let &const - замена var Константы const a = 42; a = 0; // error! const a = { value: 0 } a.value = 42; // ok a = 'new value'; // error!
  • 9.
    2. Литералы объектов Свойства leteventName = 'miniq'; let city = 'Vitebsk'; let conference = { eventName, city, getCity() { return this.city; } }; //эквивалентно eventName: eventName, city: city, getCity: function() { return this.city; }
  • 10.
    2. Литералы объектов Свойства leteventName = 'miniq'; let city = 'Vitebsk'; let conference = { eventName, city, getCity() { return this.city; } }; //эквивалентно eventName: eventName, city: city, getCity: function() { return this.city; }
  • 11.
    2. Литералы объектов [вычисляемыеимена свойств] let eventName = 'miniq'; let city = 'Vitebsk'; let conference = { eventName, city, [city + '-17']: guestsCount, getCity() { return this.city; } }; conference[city + '-17'] = guestsCount;
  • 12.
    2. Литералы объектов Ссылкана прототип __proto__ let eventName = 'miniq'; let city = 'Vitebsk'; let conference = { __proto__: Event, eventName, city, [city + '-17']: guestsCount, getCity() { return this.city; } };
  • 13.
    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
  • 14.
    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' }
  • 15.
    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' }
  • 16.
    3. Деструктурирующее присваивание Объекты,деструктурирование объекта-параметра $.get( '/miniq/2017', ( {guestsCount, date, time} ) => { //... }); $.get( '/miniq/2017', ( {guestsCount, ...dateAndTime} ) => { //... });
  • 17.
    3. Деструктурирующее присваивание Массивы letminiq = ['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
  • 18.
    3. Деструктурирующее присваивание Массивы letminiq = ['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
  • 19.
    4. Строки Строки-шаблоны let attendee= 'Ivan'; function getNextNumber(){/*...*/}; console.log(`Hi, ${attendee}! Your number is ${getNextNumber()}!`); Многострочные литералы let multiline = 'Yes, now it’s possible'; ` - это backtick, он живет на кнопке “ё” и помогает делать:
  • 20.
    4. Строки Строки-шаблоны let attendee= 'Ivan'; function getNextNumber(){/*...*/}; console.log(`Hi, ${attendee}! Your number is ${getNextNumber()}!`); Многострочные строки let multiline = 'Yes, now it’s possible'; ` - это backtick, он живет на кнопке “ё” и помогает делать:
  • 21.
  • 22.
    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); } }
  • 23.
  • 24.
    6. Параметры по-умолчанию functiongetHeadline(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}`); }
  • 25.
    7. Классы Как было: functionPoint(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function() { return `(${this.x}, ${this.y})`; }
  • 26.
    7. Классы Как наследовались: functionPoint(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}`; }
  • 27.
    7. Классы Как стало: classPoint { constructor(x, y) { this.x = x; this.y = y; } toString() { return `(${this.x}, ${this.y})`; } static get hello() { return 'Hi, I'm a point!' } }
  • 28.
    7. Классы Наследование: class Point{...} class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return super.toString() + ` - ${this.color}`; } }
  • 29.
    7. Классы Наследование: class Point{...} class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return super.toString() + ` - ${this.color}`; } }
  • 30.
    8. Модули Как былобез модулей? ● Проблемы с порядком загрузки ● “Сшивание” файлов ● Общая область видимости ● Все в одной куче Плохо, короче.
  • 31.
    8. Модули “Стройка встала,на стройке паралич: Прораб изобретает свой собственный кирпич” ● Module pattern ● AMD (RequireJS) ● CommonJS ● UMD
  • 32.
    8. Модули Стандартное решение:import & export // event-utility.js const config = {/*...*/} export function sendInvitation(person) {/*...*/} export function registerSomeone(person) {/*...*/}
  • 33.
    8. Модули // event-utility.js constconfig = {/*...*/} 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 {/*...*/}
  • 34.
    8. Модули // event-utility.js constconfig = {/*...*/} 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 {/*...*/}
  • 35.
    8. Модули // event-utility.js constconfig = {/*...*/} 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 {/*...*/}
  • 36.
    8. Модули // event-utility.js constconfig = {/*...*/} 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 {/*...*/}
  • 37.
    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';
  • 38.
    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';
  • 39.
    И это ещене все!.. ● Promises ● Set, Map, Weakset & Weakmap ● Итераторы, for … of ● Генераторы ● async/await ● Symbol ● Proxie ● Unicode ● ...
  • 40.
    И как этимвоспользоваться? Часть уже есть в браузерах. https://kangax.github.io/compat-table/es6/
  • 41.
    И как этимвоспользоваться? Для модулей понадобится сборщик / загрузчик: ● Webpack (мощный, но требует Webpack Ops) ● Rollup (попроще) ● SystemJS Для остального - транспайлеры ● Babel (остальные не нужны) ● Traceur
  • 42.
    И как этимвоспользоваться? Babel Как часть процесса сборки: module: { rules: [ { test: /.js$/, exclude: /(node_modules)/, use: { loader: 'babel-loader', options: { presets: ['env'] } }
  • 43.
    И как этимвоспользоваться? Babel В консоли: babel script.js --out-file script-compiled.js Или прямо на странице: <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
  • 44.
    Зачем все это? Плюсы: ●Улучшают читаемость ● Упрощают некоторые задачи ● Делают прежде неясные моменты более четкими Минусы: ● Непривычно ● Усложнение процесса сборки
  • 45.
    We need togo 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/
  • 46.