Обзор ES6 в 350 пунктах. Часть первая +31


Моя серия заметок ES6 in Depth, состоящая из 24 записей, описывает большинство синтаксических изменений и нововведений в ES6. В этой публикации я подведу итог всего изложенного в предыдущих статьях, чтобы дать возможность посмотреть еще раз на всё вместе. Также я добавил ссылки на мой блог, чтобы в случае необходимости сразу же можно было посмотреть подробнее.



Я слышал, вы любите маркированные списки, так что вот вам статья со списком, который состоит из нескольких сотен элементов.

Для начала приведу оглавление, чтобы было понятно, о чем пойдет речь. Очевидно, что оглавление – это также ненумерованный список. Обратите внимание: если хотите глубже вникнуть в эту тему, прочтите весь цикл статей и самостоятельно «поковыряйте» код ES6.

Содержание

? Введение
? Инструментарий
? Assignment Destructing
? Spread Operator и Rest Parameters
? Стрелочные функции
? Шаблонные строки
? Литералы объектов
? Классы
? Let и Const
? Символы
? Итераторы
? Генераторы
? Промайсы
? Maps
? WeakMaps
? Sets
? WeakSets
? Прокси
? Reflection
? Number
? Math
? Array
? Object
? Строки и Unicode
? Модули

Извините за такое длинное оглавление. Начинаем.

Введение

? ES6 (также известен как Harmony, es-next, ES2015) – последняя и окончательная спецификация языка.
? Окончательная спецификация ES6 была утверждена в июне 2015 года (следовательно, ES2015).
? Будущие версии языка будут называться согласно шаблону ES[YYYY], например ES2016 для ES7.
o Ежегодный релиз-цикл, необратимые изменения начинают действовать со следующего релиза.
o Так как ES6 появился раньше, чем это решение, большинство из нас всё еще называет его ES6.
o Начиная с ES2016 (ES7), мы должны использовать шаблон ES[YYYY], чтобы ссылаться на новые версии.
o Главная причина использования такого шаблона именования – оказание давления на производителей браузеров с целью как можно более быстрого внедрения последних обновлений.

Инструментарий

? Чтобы использовать ES6 сегодня, вам потребуется JavaScript-to-JavaScript транспайлер.
? Транспайлеры пришли и останутся, потому что:
o они предоставляют возможность компилировать код новой версии языка в код старой версии;
o мы будем транспайлить ES2016 и ES2017 в ES6 и т. д., когда браузерная поддержка станет лучше;
o нам потребуется улучшенный функционал source mapping;
o на сегодняшний день это самый надежный способ запускать ES6 код в продакшн (несмотря на то, что браузеры поддерживают ES5).
? У babel (транспайлера) есть киллер-фича: человекочитаемый вывод (human-readable output).
? Используйте babel, чтобы транспайлить ES6 в ES5 для статических сборок.
? Используйте babelify, чтобы внедрить babel в свой grunt, gulp или npm run процесс сборки.
? Используйте nodejs весии 4.x.x или выше – там есть весьма приличная поддержка ES6 (спасибо v8).
? Используйте babel-node с любой версией node.js – он будет транспайлить модули в ES5.
? В babel есть разрастающаяся экосистема, которая уже поддерживает ES2016 и некоторые плагины.
? Прочитайте A Brief History of ES6 Tooling.

Assignment Destructuring

? var {foo} = pony то же, что var foo = pony.foo.
? var {foo: baz} = pony то же, что var baz = pony.foo
? Можно задавать значения по умолчанию, var {foo='bar'} = baz вернет foo: 'bar', если baz.foo является undefined.
? Можно затащить сколько угодно свойств, под псевдонимами или без них:
o var {foo, bar: baz} = {foo: 0, bar: 1} даст foo: 0 и baz: 1.
? Можно пойти дальше: var {foo: {bar}} = { foo: { bar: 'baz' } } даст bar: 'baz'.
? Этому тоже можно назначить псевдоним: var {foo: {bar: deep}} = { foo: { bar: 'baz' } } даст вам deep: 'baz'.
? Свойства, которые не были найдены, по-прежнему возвращают undefined var {foo} = {}.
? Вложенные свойства, которые не были найдены, возвращают ошибку var {foo: {bar}} = {}.
? Это также работает для массивов, [a, b] = [0, 1] вернет a: 0 и b: 1.
? Можно пропускать элементы в массиве, [a,, b] = [0, 1, 2], получаем a: 0 и b: 2.
? Переменные можно менять местами, не прибегая к помощи третьей “aux” переменной, [a, b] = [b, a].
? Можно также использовать destructuring в параметрах функций:
o присваивание значений по умолчанию function foo (bar=2) {};
o эти значения могут также быть и объектами function foo (bar={ a: 1, b: 2 }) {};
o можно деструктурировать bar полностью: function foo ({ a=1, b=2 }) {};
o если ничего не было передано, по умолчанию получаем пустой массив: function foo ({ a=1, b=2 } = {}) {}.

Прочитайте ES6 JavaScript Destructuring in Depth.

Spread Operator и Rest Parameters

? Rest parameters – это как arguments, только лучше.
o сигнатура метода объявляется как function foo (...everything) {};
o everything – это массив со всеми параметрами, переданными в foo;
o можно присвоить имя нескольким параметрам перед ...everything, например: function foo (bar, ...rest) {};
o эти параметры будут исключены из ...rest;
o ...rest должен быть последним параметром в списке.
? Spread operator – это даже лучше, чем магия, он также обозначается при помощи … синтаксиса:
o отменяет необходимость apply при вызове методов, fn(...[1, 2, 3]) – то же, что fn(1, 2, 3);
o упрощенная конкатенация: [1, 2, ...[3, 4, 5], 6, 7];
o позволяет слепить массивоподобные элементы или коллекции в массивы [...document.querySelectorAll('img')];
o также полезен при destructing [a,, ...rest] = [1, 2, 3, 4, 5] возвращает a: 1 и rest: [3, 4, 5];
o делает new + .apply простым, new Date(...[2015, 31, 8]).
? Прочитайте ES6 Spread and Butter in Depth.

Стрелочные функции

? Лаконичный способ объявить функцию param => returnValue.
? Полезно при функциональном программировании, [1, 2].map(x => x * 2).
? Есть несколько разных способов использования (займет некоторое время, чтобы выработать привычку):
0 p1 => expr отлично подходит, если параметр один;
0 p1 => expr имеет неявный оператор return для выражения expr;
0 чтобы неявно вернуть объект, нужно обернуть его в круглые скобки () => ({ foo: 'bar' }), иначе получите ошибку;
0 круглые скобки необходимы, когда у вас 0, 2 или больше параметров () => expr or (p1, p2) => expr;
0 фигурные скобки в правой части представляют блок кода, в котором может содержаться несколько инструкций () => {};
0 при использовании такого синтаксиса неявного return нет, его нужно писать () => { return 'foo' }.
? Нельзя статически давать стрелочной функции имя, но тесты производительности намного лучше для большинства методов без имени.
? Стрелочные функции привязаны к лексическому окружению:
0 this это тот же контекст this, что и в родительском лексическом окружении;
0 this нельзя изменить при помощи .call, .apply, или похожих методов “reflection”-типа.
? Прочитайте ES6 Arrow Functions in Depth.

Шаблонные строки

? Строки можно объявлять при помощи обратных кавычек (`) в дополнение к одинарным и двойным.
? Строки с обратными кавычками являются шаблонными строками.
? Шаблонные строки могут быть многострочными.
? Шаблонные строки позволяют производить промежуточные вычисления `ponyfoo.com is ${rating}`, где rating – это переменная.
? Можно использовать любое валидное js-выражение для вычисления, например: `${2 * 3}` или `${foo()}`.
? Можно использовать помеченные шаблоны, чтобы изменить логику вычисления промежуточных значений:
0 добавить префикс fn к fn`foo, ${bar} and ${baz}`;
0 fn вызывается единожды с template, ...expressions;
0 template – это ['foo, ', ' and ', ''], а expressions – это [bar, baz];
0 результат fn становится значением шаблонной строки;
0 возможные примеры использования: очистка вводимых выражений от лишних данных, парсинг параметров и т. д.
? Шаблонные строки практически во всем лучше строк, обернутых в одинарные или двойные кавычки.
? Прочитайте ES6 Template Literals in Depth.

Литералы объектов

? Вместо { foo: foo }, можно писать просто { foo } – сокращенная форма записи пары свойство–значение.
? Вычисляемые имена свойств: { [prefix + 'Foo']: 'bar' }, где prefix: 'moz' возвращает { mozFoo: 'bar' }.
? Нельзя одновременно пытаться использовать две предыдущих особенности, запись {[foo]} – невалидна.
? Определения методов можно сделать более лаконичными при помощи следующего синтаксиса: { foo () {} }.
? Смотрите также секцию Object.
? Прочитайте ES6 Object Literal Features in Depth.

Классы

? Не «традиционные» классы, а синтаксический сахар поверх механизма наследования прототипов.
? Синтаксис похож на объявление объектов class Foo {}.
? Методы экземпляра new Foo().bar объявляются при помощи упрощенного синтаксиса литералов объекта class Foo { bar () {} }.
? Статические методы – Foo.isPonyFoo() – нуждаются в префиксе, ключевом слове static class Foo { staticisPonyFoo () {} }.
? Метод конструктора class Foo { constructor () { /* initialize instance */ }.
? Прототипное наследование с упрощенным синтаксисом class PonyFoo extends Foo {}.
? Прочитайте ES6 Classes in Depth.

Let и Const

? let и const – это альтернативы var при объявлении переменных.
? let имеет блочную область видимости, а не лексическую, по отношению к родительской функции.
? let поднимается в верхнюю часть блока, в то время как var поднимается в верхнюю часть функции.
? «Временная мертвая зона» или просто ВМЗ:
0 начинается в начале блока, в котором происходит объявление let foo;
0 заканчивается в том месте кода, где происходит объявление let foo (здесь «подъем» не имеет значения);
0 попытки доступа или определения foo внутри ВМЗ (до того, как будет выполнена инструкция let foo) приведут к ошибке;
0 помогает сократить число загадочных багов, в которых значение переменной претерпевает изменения раньше, чем происходит ее объявление.
? const также имеет блочную область видимости, «подъем» и следует семантике ВМЗ.
? Переменные const должны быть объявлены при помощи инициализатора const foo = 'bar'.
? Определение const после инициализации побуждает тихую ошибку (или не тихую – в строгом режиме).
? Переменные const не делают переменную неизменяемой:
0 const foo = { bar: 'baz' } значит, что foo всегда будет ссылаться на объект в правой части выражения;
0 const foo = { bar: 'baz' }; foo.bar = 'boo' не бросит исключение.
? Определение переменной с таким же именем – бросит.
? Предназначен для того, чтобы исправлять ошибки, когда вы переопределяете переменную и теряете ссылку на первоначальный объект.
? В ES6 функции имеют блочную область видимости:
0 предотвращают утечку данных через механизм «всплытия» { let _foo = 'secret', bar = () => _foo; };
0 не ломают пользовательский код в большинстве ситуаций и, как правило, являются тем, что вам нужно.
? Прочитайте ES6 Let, Const and the “Temporal Dead Zone” (TDZ) in Depth.




К сожалению, не доступен сервер mySQL