CSS-live.ru

Обзор ES6 в 350 пунктах

Перевод статьи ES6 Overview in 350 Bullet Points  с сайта ponyfoo.com, опубликовано на css-live.ru с разрешения автора — Николаса Беваквы.

Моя серия статей «ES6 изнутри» состоит из 24 статей, охватывающих большинство изменений синтаксиса и возможностей, появившихся в ES6. Цель этой статьи — резюмировать это всё, что даст вам практическое понимание большей части ES6, чтобы можно было быстро начать работать с ним. Я также привёл ссылки на все статьи «ES6 изнутри», чтобы вы легко могли перейти к нужной вам теме.

Я слышал, что вы любите перечисления по пунктам, так что я запилил статью с сотнями этих мерзавцев. Для начала, вот вам оглавление со всеми рассматриваемыми темами. В нем перечисляются пункты — очевидно. Но всё-таки, если хотите, чтобы эти идеи проникли в ваш мозг, вам придётся уделить гораздо больше времени на изучение предмета, проштудировав углубленные серии и экспериментируя со своим собственным кодом ES6.

Оглавление

Извиняюсь за длинное оглавление, итак, приступим.

Введение

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

(назад к оглавлению)

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

  • Чтобы заставить ES6 работать сегодня, необходим транспилер JavaScript в JavaScript.
  • Транспилеры уже вошли в обиход
    • Они позволяют компилировать код из последней версии в старые версии языка
    • Когда браузерная поддержка станет лучше, мы сможем компилировать ES2016 и ES2017 в ES6 и в ещё более ранние версии.
    • Нам понадобится лучшая функциональность построения карт кода
    • Транспилеры — это самый надёжный способ запустить исходный код ES6 на реальном проекте сегодня (хотя браузеры получат ES5)
  • У Babel (транспилера) есть уникальная черта: красивый вывод.
  • Используйте babel, чтобы скомпилировать ES6 в ES5 для статических сборок.
  • Используйте babelify, чтобы включить babel в ваш процесс сборки на Gulp, Grunt или npm run
  • Используйте Node.js v4.x.x или выше, поскольку у них есть приличная встроенная поддержка ES6, благодаря v8.
  • Используйте babel-node с любой версией node, поскольку он компилирует модули в ES5.
  • У Babel есть развитая экосистема, которая уже поддерживает кое-что из ES2016, и поддерживает плагины.
  • Читайте «Краткую историю инструментария ES6»

(назад к оглавлению)

Деструктурирующее присваивание

  • var {foo} = pony эквивалентно var foo = pony.foo
  • var {foo: baz} = pony эквивалентно var baz = pony.foo
  • Можно подставить значение по умолчанию, если baz.foo равно undefined, то результатом var {foo='bar'} = baz будет foo: 'bar'
  • Выводите любое количество свойств, с псевдонимами или нет.
    • 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
  • Можно обменивать значения без «вспомогательной» переменной: [a, b] = [b, a]
  • Также можно использовать деструктуризацию в параметрах функции
    • Присваивать значения по умолчанию, напр. function foo (bar=2) {}
    • Также, эти значения могут быть объектами: function foo (bar={ a: 1, b: 2 }) {}
    • Деструктировать bar полностью, например function foo ({ a=1, b=2 }) {}
    • Подставлять по умолчанию пустой объект, если в функцию ничего не передается, напр. function foo ({ a=1, b=2 }= {}) {}
  • Читайте «Деструктурирование в JavaScript (ES6) изнутри»

(назад к оглавлению)

Оператор расширения и оставшиеся параметры

  • Оставшиеся параметры — это такой улучшенный объект arguments
    • Вы объявляете их в сигнатуре метода, например function foo (...everything) {}
    • Everything — это массив со всеми параметрами, переданными в foo
    • Можно назвать несколько параметров перед …everything, напр. function foo (bar, ...rest) {}
    • Названные параметры исключаются из …rest
    • ...rest должен быть последним параметром в списке
  • Оператор расширения — лучше магии, также указывается с помощью синтаксиса ...
    • Позволяет избежать .apply при вызове методов, fn(...[1, 2, 3]) эквивалентно fn(1, 2, 3)
    • Более простая конкатенация [1, 2, ...[3, 4, 5], 6, 7]
    • Приводит итерируемые или массиво-подобные объекты к массиву, напр. [...document.querySelectorAll('img')]
    • Также это полезно при деструктировании, [a, , ...rest] = [1, 2, 3, 4, 5] даёт a: 1 и rest: [3, 4, 5]
    • Позволяет делать new + apply() без усилий, new Date(...[2015, 31, 8])
  • Читайте «Вкусности ES6 Spread в подробностях»

(назад к оглавлению)

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

  • Краткий способ объявить функцию, напр. param => returnValue
  • Полезно для такой функциональщины, как [1, 2].map (x => x * 2)
  • Доступно несколько разновидностей, первое время может быть непривычным
    • p1 => expr хорошо для одного параметра
    • У p1 => expr есть неявный оператор return для данного выражения expr
    • Чтобы неявно вернуть объект, оберните его в круглые скобки () => ({ foo: 'bar' }), иначе вы получите ошибку.
    • Скобки требуются для нуля, двух или более параметров, () => expr или (p1, p2) => expr
    • Фигурные скобки в правой части представляют блок кода, в котором может быть множество операторов, () => {}
    • При использовании блока кода неявного return нет, поэтому вам придётся написать его самим — () => { return 'foo' }
  • Стрелочные функции нельзя именовать статически, но для большинства методов назначение имен во время выполнения сейчас намного эффективнее.
  • Стрелочные функции связаны с их лексической областью
    • this — тот же самый контекст this, что у родительской области
    • this нельзя изменять при помощи .call, .apply или аналогичных «reflection»-подобных методов
  • Читайте «ES6: стрелочные функции изнутри»

(назад к оглавлению)

Литералы шаблонов

  • Можно объявлять строки с помощью ` (обратных кавычек) в дополнение к " и '.
  • Строки, обёрнутые в обратные кавычки — это литералы шаблона
  • Литералы шаблона могут быть многострочными
  • Литералы шаблона могут интерполироваться, напр. `ponyfoo.com is ${rating}` где rating, где — переменная
  • В интерполяции можно использовать любые допустимые выражения JavaScript, такие как `${2 * 3}` или `${foo()}`
  • Чтобы изменить способы интерполяции выражений, можно использовать помеченные шаблоны
    • Добавьте префикс fn в fn`foo, ${bar} and ${baz}`
    • fn вызывается один раз с параметрами template, ...expressions
    • template — это ['foo, ', ' and ', ''] и выражения — [bar, baz]
    • Результат fn становится значением литерала шаблона
    • Возможные варианты использования включают фильтрацию вводимых выражени, парсинг параметров и т.д.
  • Литералы шаблона почти всегда лучше строк, обёрнутых в одиночные или двойные кавычки.
  • Читайте «ES6: литералы шаблона изнутри»

(назад к оглавлению)

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

  • Вместо { foo: foo } можно просто делать { foo } — известное как сокращённая запись для значения свойства
  • Вычисляемые имена свойства, { [prefix + 'Foo'] : 'bar' }, где prefix: 'moz', даст { mozFoo: 'bar' }
  • Нельзя комбинировать вычисляемые имена свойств и короткие записи для значения свойства, { [foo] } — невалидно
  • Определения метода в литерале объекта можно объявить при помощи альтернативного, более лаконичного синтаксиса, { foo () {} }
  • Смотрите также раздел «Object»
  • Читайте «ES6: возможности литерала объекта изнутри»

(назад к оглавлению)

Классы

  • Не «традиционные» классы, синтаксический сахар поверх прототипного наследования
  • Синтаксис напоминает объявление объектов, class Foo {}
  • Методы экземпляра — new Foo().bar — объявляются при помощи короткого синтаксиса для литерала объекта, class Foo { bar () {} }
  • Статические методы — Foo. isPonyFoo() — нужно предварять ключевым словом static, class Foo { static isPonyFoo () {} }
  • Метод конструктора class Foo { constructor () { /* инициализировать экземпляр */ } }
  • Прототипное наследование делается с помощью простого синтаксиса: class PonyFoo extends Foo {}
  • Читайте «ES6: классы изнутри»

(назад к оглавлению)

Ключевые слова let и const

  • let и const — альтернатива var для объявления переменных
  • У let область видимости на уровне блока вместо лексической области видимости в function
  • let поднимается в верх блока, а объявления var — в верх функции
  • «Временная мёртвая зона» — сокращённо «ВМЗ»
    • Начинается в начале блока, где был объявлен let foo
    • Заканчивается в месте размещения оператора let foo в коде пользователя (поднятие здесь значения не имеет)
    • Попытки обратиться к foo или присвоить ей значение внутри ВМЗ (до оператора let foo) приведут к ошибке
    • Помогает предотвратить таинственные баги, когда переменная обрабатывается до ее объявления
  • У const тоже область видимости на уровне блока, оно тоже поднимается и тоже ограничено семантикой ВМЗ
  • Переменные const должны быть объявлены при помощи инициализатора, const foo = 'bar'
  • Присваивание const после инициализации тихо отбрасывается (или громкос исключением при строгом режиме)
  • Переменные const не делают присвоенное значение неизменным
    • const foo = { bar: 'baz' } означает, что foo будет всегда ссылаться на объект в правой части
    • const foo = { bar: 'baz' }; foo.bar = 'boo' не выбросит исключение
  • Объявление переменной с тем же именем выбросит исключение
  • Предназначен для исправления ошибок при переназначении переменной и потере ссылки, которая была передана где-то ещё.
  • В ES6 у функций блочная область видимости
    • Предотвращает утечку секретов блочной области видимости при поднятии, {let _foo = 'secret', bar = () => _foo; }
    • Не ломает код пользователя в большинстве ситуаций, и это обычно то, что вы хотите в любом случае
  • Читайте «ES6: Let, Const и “Временная мёртвая зона” (ВМЗ) изнутри»

(назад к оглавлению)

Символы

  • Новый примитивный тип в ES6
  • Можно создавать собственные символы при помощи var symbol = Symbol()
  • Можно добавлять описание для отладки, напр. Symbol('ponyfoo')
  • Символы неизменны и уникальны. Symbol(), Symbol(), Symbol('foo') и Symbol('foo') все разные
  • Символы имеют тип symbol, так что: typeof Symbol() === 'symbol'
  • Можно также создавать глобальные символы с помощью Symbol.for(key)
    • Если символ с предоставленным key уже существует, то этот символ и вернется
    • Иначе, будет создан новый символ, также используя key в качестве его описания
    • Symbol.keyFor(symbol) — обратная функция, берущая symbol и возвращающая его key
    • Глобальные символы максимально глобальны или всеконтекстные. Чтобы найти эти символы во время процесса выполнения, применяется единый регистр для…
      • Контекста window
      • Контекст eval
      • Контекст <iframe>, Symbol.for('foo') === iframe.contentWindow.Symbol.for('foo')
  • Есть также «известные» символы
    • Не в глобальном регистре, доступные через Symbol[name], напр: Symbol.iterator
    • Всеконтекстные, что значит, что Symbol.iterator === iframe.contentWindow.Symbol.iterator
    • Используется спецификацией для определения протоколов, таких как протокол iterable над Symbol.iterator
    • Не являются «известными» в бытовом смысле
  • Перебор свойств-символов является сложным, но не невозможным и уж точно не приватным
    • Символы скрыты для всех «reflection»-методов, появившихся до ES6
    • Символы доступны через Object.getOwnPropertySymbols
    • Вы не наткнётесь на них случайно, но найдёте их при активном поиске
  • Читайте «ES6: символы изнутри»

(назад к оглавлению)

Итераторы

  • Итератор и протокол итерации определяют способ перебора любого объекта, а не только массивов и им подобных
  • Известный Symbol используется для присвоения итератора к любому объекту
  • var foo = { [Symbol.iterator]: iterable}, или foo[Symbol.iterator] = iterable
  • iterable — это метод, возвращающий объект iterator, у которого есть метод next
  • Метод next возвращает объекты с двумя свойствами, value и done
    • Свойство value указывает текущее значение в итерируемой последовательности
    • Свойство done указывает, есть ли какие-нибудь ещё элементы для перебора
  • Объекты со значением [Symbol.iterator]итерируемые, поскольку они подписаны на итерируемый протокол
  • Кое-что из встроенного, напр. Array, String, или arguments – и NodeList в браузерах — итерируемые в ES6 по умолчанию
  • По итерируемым объектам можно пройтись циклом при помощи for..of, напр. for (let el of document.querySelectorAll('a'))
  • Итерируемые объекты могут получаться с помощью оператора расширения, напр. [...document.querySelectorAll('a')]
  • Также можно использовать Array.from(document.querySelectorAll('a')), чтобы превратить итерируемую последовательность в массив
  • Итераторы ленивы, и даже с теми из них, в результате которых образуется бесконечная последовательность, вполне может получиться корректная программа
  • Будьте осторожны, не пытайтесь синтезировать бесконечную последовательность с помощью … или Array.from, поскольку это приведёт к бесконечному циклу
  • Читайте «ES6: Итераторы изнутри»

(назад к оглавлению)

Генераторы

  • Функции-генераторы — это особый вид итератора, который можно объявить при помощи синтаксиса function* generator () {}
  • Функции-генераторы используют yield, чтобы создать последовательность элементов
  • Функции-генераторы также могут использовать yield* для делегирования в другую функцию генератора — или любой итерируемый объект
  • Функции-генераторы возвращают объект генератора, который реализует оба протокола — итерируемый и итератор
    • Если g = generator(), g придерживается итерируемого протокола, поскольку g[Symbol.iterator] — это метод
    • Если g = generator(), g придерживается протокола итератора, поскольку g.next — это метод
    • Итератор для объекта генератора g — это сам генератор: g[Symbol.iterator]() === g
  • Доставайте значения, используя Array.from(g), [...g], for (let item of g), или просто вызывая g.next()
  • Выполнение функции генератора приостанавливается, запоминая последнюю позицию, в четырёх различных случаях
    • Выражение yield, возвращающее последнее значение в последовательности
    • Оператор return, возвращающий последнее значение в последовательности
    • Оператор throw останавливает выполнение в генераторе полностью
    • Функция-генератор дошла до конца, о чем сообщает { done: true }
  • Как только последовательность g закончилась, g.next() просто возвращает { done: true } без какого-либо эффекта
  • Легко создать асинхронные потоки, которые воспринимаются синхронными
    • Возьмите пользовательскую функцию генератора
    • Пока асинхронные операции выполняются, пользовательский код приостанавливается
    • Вызовите метод g.next(), чтобы возобновить выполнение в пользовательском коде
  • Читайте «ES6: генераторы изнутри»

(назад к оглавлению)

Промисы

  • Соответствуют спецификации Промисы/A+, были широко реализованы на практике ещё до стандартизации ES6 (напр. bluebird)
  • Поведение промисов похоже на дерево. Добавляйте ветки с помощью p.then(handler) и p.catch(handler)
  • Создавайте новый промис p при помощи new Promise((resolve, reject) => { /* resolver */ })
    • Обратный вызов resolve(value) выполнит промис с переданным value
    • Обратный вызов reject(reason) отклонит p отклонит с ошибкой reason
    • Можно вызвать эти методы асинхронно, блокируя более глубокие ветки дерева промиса
  • Каждый вызов p.then и p.catch создаёт другой промис, который блокируется, когда p завершается
  • Промисы входят в состояние ожидания и завершаются, когда они выполняются, либо отклоняются
  • Промисы могут завершиться только один раз, после этого они находятся в завершенном состоянии. Завершенные промисы разблокируют более глубокие ветки
  • Можно добавлять любое количество промисов к любому количеству веток, которое вам нужно
  • Каждая ветка будет выполняться либо обработчиками .then, либо обработчиками .catch, но не обоими сразу
  • Обратный вызов .then может преобразовывать результат предыдущей ветки, возвращая значение
  • Обратный вызов .then может блокировать другой промис, возвращая его
  • p.catch(fn).catch(fn) не выполнят то, что вы хотите — если только вы не хотели поймать ошибку в обработчике ошибки
  • Promise.resolve(value) создаёт промис, который выполняется с предоставленным value
  • Promise.reject(reason) создаёт промис, который отклоняется с переданным reason
  • Promise.all(...promises) создаёт промис, который завершается, когда все ...promises выполнены или один из них отклонён
  • Promise.race(...promises) создаёт промис, который завершается, как только один из ...promises завершён
  • Используйте Promisees — интерактивную наглядную «песочницу» для промисов — чтобы лучше понять промисы
  • Читайте «ES6: промисы изнутри»

(назад к оглавлению)

Объект Map

  • Замена общего паттерна для создания ассоциативных массивов с помощью простых объектов JavaScript
    • Позволяет избежать проблем безопасности с пользовательскими ключами
    • Любые значения могут быть ключами, в качестве key для записи можно даже использовать элементы DOM или функции.
  • Map придерживается итерируемого протокола
  • Создавайте mapс помощью new Map()
  • Инициализируйте ассоциативный массив с помощью iterable, напр. [[key1, value1], [key2, value2]] в new Map(iterable)
  • Используйте map.set(key, value) для добавления записей
  • Используйте map.get(key) для получения записи
  • Проверяйте key с помощью map.has(key)
  • Удаляйте записи с помощью map.delete(key)
  • Перебирайте map с помощью for (let [key, value] of map), оператора расширения, Array.from, и т.д.
  • Читайте «ES6: Методы объекта Map изнутри»

(назад к оглавлению)

Объект WeakMap

  • Напоминает Map, но кое-чем отличается
  • WeakMap не итерируется, так что вы не получите такие методы перечисления, как .forEach, .clear, и другие, которые у вас были в Map
  • Ключи WeakMap должны быть ссылочных типов. В виде ключей нельзя использовать такие значимые типы, как символы, числа или строки.
  • Записи WeakMap с ключом key, который является единственной ссылкой на указанную переменную — подлежат сборке мусора
  • Последний пункт означает, что WeakMap прекрасно подходит для хранения метаданных для объектов, пока эти объекты используются
  • Помогает избежать утечки памяти без ручного подсчёта ссылок — можно провести аналогию между WeakMap и IDisposable в .NET
  • Читайте «ES6: Методы объекта WeakMap изнутри»

(назад к оглавлению)

Объект Set

  • Напоминает Map, но есть кое-какие отличия
  • У Set нет ключей, а есть только значения
  • set.set(value) не выглядит правильным, поэтому вместо него есть set.add(value)
  • У методы объекта Set не может быть повторяющихся значений, поскольку значения также используются в качестве ключей
  • Читайте «ES6 методы объекта Set изнутри»

(назад к оглавлению)

Объект WeakSet

  • WeakSet — своего рода гибрид Set и WeakMap
  • WeakSet — множество, которое нельзя итерировать, и у которого нет методов перечисления
  • Значения WeakSet должны быть ссылочного типа
  • WeakSet может быть полезен для таблицы метаданных, указывающую, активно ли используется ссылка или нет
  • Читайте «ES6: методы объекта WeakSet изнутри»

(назад к оглавлению)

Прокси

  • Прокси создаются с помощью new Proxy(target, handler), где target — любой объект, а handler — конфигурация
  • По умолчанию proxy ведет себя как прямая переадресация к основному объекту target
  • Обработчики определяют, как происходит доступ к основному объекту target посредством обычной семантики доступа к свойствам объекта
  • Вы подсовываете ссылки proxy и сохраняете строгий контроль над тем, как можно взаимодействовать с target
  • Обработчики также известны как «ловушки/перехватчики», эти термины используются как синонимы
  • Вы можете создать прокси, которые можно отменять, с помощью Proxy.revocable(target, handler)
    • Этот метод возвращает объект со свойствами proxy и revoke
    • Вы могли бы деструктировать var {proxy, revoke} = Proxy.revocable(target, handler)для удобства
    • Аналогично можно настроить proxy и при помощи new Proxy(target, handler)
    • После вызова revoke(), proxy прекратит любые операции, что делает его очень удобным, когда вы не доверяете пользователям
  • get — ловит proxy.prop и proxy['prop']
  • set — ловит proxy.prop = value и proxy['prop'] = value
  • has — ловит оператор in
  • deleteProperty — ловит оператор delete
  • defineProperty — ловит Object.defineProperty и декларативные альтернативы
  • enumerate — ловит циклы for..in
  • ownKeys — ловит Object.keys и связанные с ним методы
  • apply — ловит вызовы функции
  • construct — ловит использование оператора new
  • getPrototypeOf — ловит внутренние вызовы в [[GetPrototypeOf]]
  • setPrototypeOf — ловит вызовы в Object.setPrototypeOf
  • isExtensible — ловит вызовы в Object.isExtensible
  • preventExtensions — ловит вызовы в Object.preventExtensions
  • getOwnPropertyDescriptor — ловит вызовы в Object.getOwnPropertyDescriptor
  • Читайте «ES6: прокси изнутри»
  • Читайте «ES6: ловушки прокси изнутри»
  • Читайте «Ещё больше про ловушки в ES6 изнутри»

(назад к оглавлению)

Объект Reflection

  • Reflection — новый статический встроенный объект (напоминает Math) в ES6
  • У методов Reflection есть разумные внутренние механизмы, напр. Reflect.defineProperty возвращает булево значение вместо выбрасывания исключения
  • Есть метод Reflection для каждого обработчика-ловушки прокси, и они представляют поведение по умолчанию для каждой ловушки
  • В дальнейшем, новые reflection-методы наподобие Object.keys разместятся в пространстве имён Reflection
  • Читайте «ES6: Reflection изнутри»

(назад к оглавлению)

Число

  • Используйте префикс 0b для двоичных и 0o — для восьмеричных целочисленных литералов
  • Number.isNaN и Number.isFinite — такие же, как и их глобальные тёзки, за исключением того, что они не приводят подаваемое им на вход значение к Number
  • Number.parseInt и Number.parseFloat — точно такие же, как и их глобальные тёзки
  • Number.isInteger проверяет, является ли подаваемое на вход значением Number, у которого нет дробной части
  • Number.EPSILON помогает выяснить пренебрежимую разница между двумя числами — напр. 0.1 + 0.2 и 0.3
  • Number.MAX_SAFE_INTEGER — наибольшее целое число, которое может быть безопасно и точно представлено в JavaScript
  • Number.MIN_SAFE_INTEGER — наименьшее целое число, которое может быть безопасно и точно представлено в JavaScript
  • Number.isSafeInteger проверяет, находится ли целое число в пределах тех границ, которые могут быть представлены безопасно и точно
  • Читайте «ES6: усовершенствования Number изнутри»

(назад к оглавлению)

Объект Math

  • Math.sign — функция, возвращающая знак числа
  • Math.trunc — Возвращает целую часть числа
  • Math.cbrt — возвращает кубический корень из значения
  • Math.expm1 — возвращает в степени value с вычетом 1 , или evalue - 1
  • Math.log1p — возвращает натуральный логарифм value + 1, или ln(value + 1)
  • Math.log10 — возвращает десятичный логарифм числа
  • Math.log2 — возвращает двоичный логарифм значения, или log2(value)
  • Math.sinh — возвращает гиперболический синус числа
  • Math.cosh — возвращает гиперболический косинус числа
  • Math.tanh — возвращает гиперболический тангенс числа
  • Math.asinh — возвращает гиперболический арксинус числа
  • Math.acosh — возвращает гиперболический арккосинус числа
  • Math.atanh — возвращает гиперболический арктангенс числа
  • Math.hypot — квадратный корень из суммы квадратов
  • Math.clz32 — возвращает количество ведущих нулей 32-битного представления числа
  • Math.imul — (как в C) возвращает результат умножения 32-битных чисел
  • Math.fround — возвращает наиболее близкое представление данного числа в виде числа с плавающей запятой одинарной точности
  • Читайте «ES6: дополнения для объекта Math изнутри»

(назад к оглавлению)

Массив

  • Array.from — создаёт экземпляры Array из массиво-подобных объектов, таких как arguments или итерируемых объектов
  • Array.of — напоминает new Array(...items), но без особых случаев
  • Array.prototype.copyWithin — копирует последовательность элементов массива в другое место массива
  • Array.prototype.fill — заполняет все элементы существующего массива предоставленным значением
  • Array.prototype.find — возвращает первый элемент, удовлетворяющий условию проверяющей функции
  • Array.prototype.findIndex — возвращает индекс первого элемента, удовлетворяющего условию проверяющей функции
  • Array.prototype.keys — возвращает итератор , дающий последовательность, содержащую ключи массива
  • Array.prototype.values — возвращает итератор, дающий последовательность, содержащую значения массива
  • Array.prototype.entries — возвращает итератор массива, содержащий пару ключ значение каждого индекса в массиве
  • Array.prototype[Symbol.iterator] — в точности такой же, как метод Array.prototype.values
  • Читайте «ES6: расширения для Array изнутри»

(назад к оглавлению)

Объект

(назад к оглавлению)

Объект String и юникод

(назад к оглавлению)

Модули

  • В системе модулей ES6 по умолчанию включён строгий режим
  • Модули в ES6 — это файлы, которые производят export API (т.е. экспортируют его)
  • export default value экспортирует привязку по умолчанию
  • export var foo = 'bar' экспортирует именованную привязку
  • Именованные экспорты — привязки, которые можно изменять в любое время из модуля, который их экспортирует
  • export { foo, bar } экспортирует список названных экспортов
  • export { foo as ponyfoo } позволяет ссылаться на экспорт как на ponyfoo
  • export { foo as default } выбирает именованный экспорт в качестве экспорта по умолчанию
  • Хорошим тоном будет ставить export default api в конце всех ваших модулей, где api — объект, что позволяет избежать путаницы
  • Загрузка модуля зависит от конкретной реализации, позволяет взаимодействовать с CommonJS
  • import 'foo' загружает модуль foo в текущий модуль
  • import foo from 'ponyfoo' присваивает экспорт ponyfoo по умолчанию в локальную переменную foo
  • import {foo, bar} from 'baz' импортирует именованные экспорты foo и bar из модуля baz
  • import {foo as bar} from 'baz' импортирует названный экспорт foo, но с псевдонимом в виде переменной bar
  • import {default} from 'foo' также импортирует экспорт по умолчанию
  • import {default as bar} from 'foo' импортирует экспорт по умолчанию с псевдонимом bar
  • import foo, {bar, baz} from 'foo' сочетает foo по умолчанию с именованными экспортами bar и bazв одном объявлении
  • import * as foo from 'foo' импортирует объект пространства имён
    • Содержит все названные экспорты в foo[name]
    • Содержит экспорт по умолчанию в foo.default, если экспорт по умолчанию был объявлен в модуле
  • Читайте «ES6: дополнения в модулях изнутри»

(назад к оглавлению)

Пора прийти в себя после перечисления пунктов. Опять же, я предупреждал вас, чтобы вместе этого вы прочитали серию статей. Не забудьте подписаться и, может быть, даже помочь «Pony Foo» удержаться на плаву. Кстати, вы ещё не попробовали «Konami code»?

P.S. Это тоже может быть интересно:

13 комментариев

  1. «let поднимается в верх блока»
    Если здесь имеется в виду hoisting, то у let его как раз нету. Переменная, объявленная через let, недоступна перед объявлением и обращение к ней вызовет ReferenceError.

    1. При переводе мы тоже долго ломали голову над этим моментом. Но автор оригинала настаивает (в ответе на первый коммент к оригиналу), что hoisting у let всё-таки есть, просто такой вот загадочный — переменная в блоке как бы есть (ссылка на соотв. идентификатор зарезервирована), но до точки объявления ее как бы нет (та самая невозможность обратиться, она же TDZ/ВМЗ).

      Интересно, что в рамках одного домена mozilla.org на тему поднятия let можно прочесть диаметрально противоположное: в MDN сказано, что его нет, а в статье — что всё-таки есть (хоть и не такое «слепое», как для var). На мой взгляд, этот вопрос неплохо проясняется в этом ответе на SO.

    1. А то, что вторая половина перевода до хабра добралась лишь через 6 дней после этой публикации, не смущает? :)

  2. Максим, не в обиду, но за подобный перевод надо руки отрывать.
    Например, вы радикально переврали целый топик, полностью исказив его смысл.
    И в названии топика, и дальше по тексту: присваивание НЕ деструктивное! Присваивание — деструктурирующее! Или вы искренне не понимаете, что это два совершенно разных смысла?

  3. Array.prototype.fill — заполняет все элементы существующего массива предоставленным значением
    Array.prototype.fill — возвращает первый элемент, удовлетворяющий условию проверяющей функции

  4. Object.is — как программное использование оператора ===, но также дает true при сравнении NaN c NaN и +0 c -0

    -0 === +0
    // <- true
    Object.is(-0, +0)
    // <- false

  5. В комментарии сверху ссылка выставилась, в статье — голые тэги.

    И еще:

    Number.MAX_SAFE_INTEGER — наибольшее целое число, которое может быть безопасно и точно представлено в JavaScript
    Number.MAX_SAFE_INTEGER — наименьшее целое число, которое может быть безопасно и точно представлено в JavaScript

    Это уж не говоря о ошибках и опечатках.

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.