Обзор ES6 в 350 пунктах
Перевод статьи ES6 Overview in 350 Bullet Points с сайта ponyfoo.com, опубликовано на css-live.ru с разрешения автора — Николаса Беваквы.
Моя серия статей «ES6 изнутри» состоит из 24 статей, охватывающих большинство изменений синтаксиса и возможностей, появившихся в ES6. Цель этой статьи — резюмировать это всё, что даст вам практическое понимание большей части ES6, чтобы можно было быстро начать работать с ним. Я также привёл ссылки на все статьи «ES6 изнутри», чтобы вы легко могли перейти к нужной вам теме.
Я слышал, что вы любите перечисления по пунктам, так что я запилил статью с сотнями этих мерзавцев. Для начала, вот вам оглавление со всеми рассматриваемыми темами. В нем перечисляются пункты — очевидно. Но всё-таки, если хотите, чтобы эти идеи проникли в ваш мозг, вам придётся уделить гораздо больше времени на изучение предмета, проштудировав углубленные серии и экспериментируя со своим собственным кодом ES6.
Оглавление
- Введение
- Инструментарий
- Деструктурирующее присваивание
- Оператор расширения и оставшиеся параметры
- Стрелочные функции
- Литералы шаблона
- Литералы объекта
- Классы
- Ключевые слова
let
иconst
- Символы
- Итераторы
- Генераторы
- Промисы
- Объект Map
- Объект WeakMap
- Объект Set
- Объект WeakSet
- Объекты прокси
- Метод Reflection
- Объект Number
- Объект Math
- Объект Array
- Объект Object
- Объект String и юникод
- Модули
Извиняюсь за длинное оглавление, итак, приступим.
Введение
- 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
— наибольшее целое число, которое может быть безопасно и точно представлено в JavaScriptNumber.MIN_SAFE_INTEGER
— наименьшее целое число, которое может быть безопасно и точно представлено в JavaScriptNumber.isSafeInteger
проверяет, находится ли целое число в пределах тех границ, которые могут быть представлены безопасно и точно- Читайте «ES6: усовершенствования
Number
изнутри»
Объект Math
Math.sign
— функция, возвращающая знак числаMath.trunc
— Возвращает целую часть числаMath.cbrt
— возвращает кубический корень из значенияMath.expm1
— возвращает в степениvalue
с вычетом1
, илиe
value- 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 изнутри»
Объект
Object.assign
— рекурсивная поверхностная перезапись свойствtarget , ...objects
Object.is
— как программное использование оператора===
, но также даетtrue
при сравненииNaN
cNaN
иfalse
для+0
c-0
Object.getOwnPropertySymbols
— возвращает все собственные свойства-символы , найденные в объектеObject.setPrototypeOf
— изменяет прототип. Равнозначно сеттеруtarget.__proto__
- См. также раздел «Литералы объекта»
- Читайте «ES6: изменения в
Object
изнутри»
Объект String
и юникод
- Манипуляции со строками
String.prototype.startsWith
определяет, начинается ли строка сvalue
String.prototype.endsWith
— определяет, заканчивается ли строка наvalue
String.prototype.includes
— определяет, содержит ли строкаvalue
где-либоString.prototype.repeat
— возвращает строку, повтореннуюamount
разString.prototype[Symbol.iterator]
— позволяет перебирать последовательность кодов Юникода (не символов)
- Юникод
String.prototype.codePointAt
— возвращает десятичное (по основанию 10) числовое представление кода в данной позиции в строкеString.fromCodePoint
— при заданных...codepoints
возвращает строку, созданную из их представлений в ЮникодеString.prototype.normalize
— возвращает нормализованную версию представления строки в Юникоде
- Читайте «Дополнения ES6 для строк и Юникода изнутри»
Модули
- В системе модулей ES6 по умолчанию включён строгий режим
- Модули в ES6 — это файлы, которые производят
export
API (т.е. экспортируют его) export default value
экспортирует привязку по умолчаниюexport var foo = 'bar'
экспортирует именованную привязку- Именованные экспорты — привязки, которые можно изменять в любое время из модуля, который их экспортирует
export { foo, bar }
экспортирует список названных экспортовexport { foo
as ponyfoo
}
позволяет ссылаться на экспорт как на ponyfooexport { foo
as default
}
выбирает именованный экспорт в качестве экспорта по умолчанию- Хорошим тоном будет ставить
export default api
в конце всех ваших модулей, гдеapi
— объект, что позволяет избежать путаницы - Загрузка модуля зависит от конкретной реализации, позволяет взаимодействовать с CommonJS
import 'foo'
загружает модульfoo
в текущий модульimport
foo from
'ponyfoo'
присваивает экспорт ponyfoo по умолчанию в локальную переменную fooimport {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. Это тоже может быть интересно:
«apply» все же с двумя p.
«let поднимается в верх блока»
Если здесь имеется в виду hoisting, то у let его как раз нету. Переменная, объявленная через let, недоступна перед объявлением и обращение к ней вызовет ReferenceError.
При переводе мы тоже долго ломали голову над этим моментом. Но автор оригинала настаивает (в ответе на первый коммент к оригиналу), что hoisting у let всё-таки есть, просто такой вот загадочный — переменная в блоке как бы есть (ссылка на соотв. идентификатор зарезервирована), но до точки объявления ее как бы нет (та самая невозможность обратиться, она же TDZ/ВМЗ).
Интересно, что в рамках одного домена mozilla.org на тему поднятия let можно прочесть диаметрально противоположное: в MDN сказано, что его нет, а в статье — что всё-таки есть (хоть и не такое «слепое», как для var). На мой взгляд, этот вопрос неплохо проясняется в этом ответе на SO.
Это ж все с хабра стырено
Извините, а вы разницу в переводе совсем не видите?
А то, что вторая половина перевода до хабра добралась лишь через 6 дней после этой публикации, не смущает? :)
Максим, не в обиду, но за подобный перевод надо руки отрывать.
Например, вы радикально переврали целый топик, полностью исказив его смысл.
И в названии топика, и дальше по тексту: присваивание НЕ деструктивное! Присваивание — деструктурирующее! Или вы искренне не понимаете, что это два совершенно разных смысла?
Array.prototype.fill — заполняет все элементы существующего массива предоставленным значением
Array.prototype.fill — возвращает первый элемент, удовлетворяющий условию проверяющей функции
Упс. Спасибо за внимательность! Fixed.
Object.is — как программное использование оператора ===, но также дает true при сравнении NaN c NaN и +0 c -0
-0 === +0
// <- true
Object.is(-0, +0)
// <- false
Array.prototype.find — возвращает первый элемент, удовлетворяющий условию проверяющей функции
В комментарии сверху ссылка выставилась, в статье — голые тэги.
И еще:
Number.MAX_SAFE_INTEGER — наибольшее целое число, которое может быть безопасно и точно представлено в JavaScript
Number.MAX_SAFE_INTEGER — наименьшее целое число, которое может быть безопасно и точно представлено в JavaScript
Это уж не говоря о ошибках и опечатках.
Спасибо, пофикшено!