Данная публикация является переводом статьи «Introduction to commonly used ES6 features» под авторством Zell Liew, размещенного здесь. Перевод разделён на 2 части. Перевод 2-ой части находится  здесь. JavaScript серьезно развился в последние несколько лет. Если вы изучаете язык в 2017 году и при этом не касались ECMAScript 6 (ES6), то упускаете легкий способ читать и писать на нём. Не волнуйтесь, если вы еще не знаток языка. От вас не требуется превосходно знать его, чтобы пользоваться преимуществами «бонусов», добавленных в ES6. В этой статье хотел бы поделиться восемью особенностями ES6, которые использую каждый день как разработчик, что поможет вам легче погрузиться в новый синтаксис. Примечание переводчика: в статье представлены семь особенностей («Промисы» рассматриваются в отдельной статье). Во-первых, ES6 — это огромное обновление JavaScript. Здесь приведён большой перечень особенностей (спасибо, Luke Hoban), если интересно, какие нововведения появились: Не стоит пугаться такого большого списка особенностей ES6. От вас не требуется знать все сразу. Далее поделюсь восемью особенностями, которые применяю каждый день. К ним относятся: Кстати, браузеры очень хорошо поддерживают ES6. Почти все особенности обеспечиваются нативно, если пишете код для последних версий браузеров (Edge, последние версии FF, Chrome и Safari). Для написания кода на ES6 не нужен такой инструмент, как Webpack. При отсутствии поддержки браузером всегда можно обратиться к полифиллам, созданными сообществом. Достаточно погуглить. Итак, приступим к первой особенности. В ES5 («старый» JavaScript) было принято объявлять переменные через ключевое слово var. В ES6 это слово может быть заменено let и const, двумя мощными ключевыми словами, которые делают разработку проще. Сначала обратим внимание на разницу между let и var, чтобы понять, почему let и const лучше. Сначала рассмотрим знакомый нам var. Во-первых, мы можем объявлять переменные через ключевое слово var. Как только объявление произошло, переменная может быть использована везде в текущей области видимости. В примере выше объявлена глобальная переменная me. Эта переменная также может быть использована в функции. Например, так: Однако, обратное не верно. Если переменную объявить в функции, то будет невозможно использовать её снаружи функции. Так, можем говорить, что у var область видимости «функциональная». Это означает, что всякий раз, когда переменная объявляется с помощью var в функции, она будет существовать только в пределах функции. Если переменная создается снаружи функции, она будет существовать во внешней области видимости. У let, с другой стороны, область видимости «блочная». Это означает, что всякий раз, когда переменная объявляется с помощью let, она будет существовать только в пределах блока. Подождите, но что же значит «блок»? Блоком в JavaScript называется то, что находится внутри пары фигурных скобок. Ниже примеры блоков: Разница между переменными, объявленными «блочно» и «функционально», огромна. При объявлении переменной «функционально» в дальнейшем можно случайно переписать значение этой переменной. Ниже пример: Этот пример показывает, что значение me становится 'Sleepy head' после выполнения кода внутри if блока. Такой пример, скорее всего, не вызовет какие-либо проблемы, т.к. вряд ли будут объявляться переменные с одинаковым именем. Однако любой, кто будет работать с помощью var через цикл for, может оказаться в странной ситуации из-за способа, которым объявлены переменные. Представим следующий код, который выводить переменную i четыре раза, а затем выводит i c помощью функции setTimeout. Какой результат можно ожидать при выполнения этого кода? Ниже то, что в действительности произойдет:  i будет четыре раза выведена со значением «5» в функции-таймере Как i получил значение «5» четыре раза внутри таймера? Всё из-за того, что var определяет переменную «функционально», и значение i становится равным «4» еще до того, как таймер начнёт выполняться. Для того чтобы получить правильное значение i внутри setTimeout, которая будет выполняться позже, необходимо создать другую функцию, допустим logLater, для гарантии того, что значение i не изменится в цикле for до начала выполнения setTimeout:  i правильно выводится как 1, 2, 3 и 4 Кстати, это называется замыканием. Хорошая новость в том, что «странность» «функционально» определенной области видимости, показанная на примере с for циклом, не происходит с let. Такой же пример с таймером может быть переписан так, что будет работать без добавления дополнительных функций:  i правильно выводится как 1, 2, 3 и 4 Как можно увидеть, «блочно» объявленные переменные, обходя недостатки «функционально» объявленных переменных, намного упрощают разработку. Для упрощения советую с этого момента использовать let вместо var каждый раз, когда необходимо объявлять переменные в JavaScript. Разобравшись, что делает let, рассмотрим разницу между let и const. Как и let, const также имеет «блочно» определенную область видимости. Разница в том, что значение const нельзя изменять после объявления. Раз const нельзя изменить, то можно использовать для переменных, которые не будут меняться. Допустим, на сайте имеется кнопка, которая запускает модальное окно, и мы знаем, что такая кнопка одна и изменяться не будет. В этом случае, используем const: При объявлении переменных по возможности всегда отдавайте предпочтение const вместо let, т.к. получаете дополнительную отметку, что переменная не будет переназначена. Для остальных случаев используйте let. Далее рассмотрим стрелочные функции. Стрелочные функции обозначаются стрелкой (=>), что можно увидеть повсюду в коде на ES6. Такое сокращенное обозначение применяется для создания анонимных функций. Они могут быть использованы везде, где имеется ключевое слово function. Например: Стрелочные функции довольно удобны, т.к. с их помощью можно сократить код, тем самым уменьшив места, где могут скрываться ошибки. Также код, написанный на них, легче понимать, если вы знакомы с их синтаксисом. Рассмотрим стрелочные функции поближе, чтобы научиться распознавать и использовать их. Сначала обратим внимание на создание функций. В JavaScript, вероятно, привычно создавать функции следующим способом: Второй способ создания функций связан с написанием анонимной функции и её присвоением переменной. Для создания анонимной функции необходимо вынести её название из объявления функции. Третий способ создания функций заключается в том, чтобы передавать их напрямую как аргумент в другую функцию или в метод. Этот способ является наиболее распространенным для анонимных функций. Ниже пример: Поскольку стрелочные функции в ES6 представляют собой сокращенное обозначение анонимных функций, их можно внедрять везде, где создаются анонимные функции. Ниже то, как это выглядит: Заметили сходство? По существу, удаляют ключевое слово function и заменяют стрелкой => в немного другом месте. Так в чём же заключается суть стрелочных функций? Только в замене function на =>? На самом деле дело не только в замене function на =>. Синтаксис стрелочной функции может быть изменён в зависимости от двух факторов: Под 1-ым фактором понимается количество аргументов, передаваемых стрелочной функции. Если передается только один аргумент, то можно опустить круглые скобки, в которые заключены аргументы. Если аргументы не требуются, то круглые скобки могут быть заменены нижним подчёркиванием _. Все ниже перечисленные примеры являются допустимыми стрелочными функциями. Под 2-ым фактором понимается необходимость неявного возврата. Стрелочные функции, по умолчанию, автоматически создают ключевое слово return, если код занимает одну строку и не обернут в фигурные скобки {}. Итак, ниже два равнозначных примера: Эти два фактора могут служить основанием для сокращения кода как с moreThan20, который был представлен выше: В заключение отмечу, стрелочные функции довольно хороши. Потратив немного времени и испытав их, можно привыкнуть к ним и везде использовать. Прежде чем вы присоединитесь к «сторонникам» стрелочных функций, познакомимся с другой их особенностью, которая вызывает много путаницы, а именно с лексическим this. this — уникальное ключевое слово, значение которого меняется в зависимости от контекста вызова. При вызове снаружи функции this ссылается на объект Window в браузере.  При вызове this через простую функцию оно ссылается на глобальный объект. В случае с браузерами this всегда будет Window. JavaScript всегда устанавливает this окну браузера при вызове простой функции. В свою очередь, это объясняет то, что this в функциях-таймерах типа setTimeout указывает на Window. При вызове this в методе объекта, оно ссылается на сам объект:  При вызове функции-конструктора this ссылается на конструируемый объект.  При использовании в обработчике события this ссылается на элемент, который запустил событие. Как можно заметить из ситуаций выше, значение this определяется функцией, которая его вызывает. Каждая функция устанавливает собственное значение this. В стрелочных функциях this никогда не приобретает новое значение вне зависимости от того, как функция вызвана. this всегда будет иметь такое же значение, какое имеет this в окружающем стрелочную функцию коде. Кстати, лексический означает ссылающийся (связанный), из-за чего, как полагаю, лексический this и получил своё название. Итак, это звучит запутанно, поэтому рассмотрим несколько реальных примеров. Во-первых, не используйте стрелочные функции для объявления методов объектов, т.к. в случае необходимости больше не сможешь сослаться на объект через this. Во-вторых, стрелочные функции могут не подойти для создания обработчиков событий, т.к. this больше не будет закреплен за элементом, к которому привязан обработчик события. Однако всегда можно будет получить правильный контекст для this через event.currentTarget. По этой причине было сказано, что «могут не подойти». В-третьих, лексический this может использоваться в тех ситуациях, когда привязка this может неожиданно меняться. Примером является функция-таймер, при которой не нужно будет иметь дело с this, that или self глупостями. Такое применение особенно полезно, если необходимо добавить или удалить класс спустя некоторое время: В заключение, используйте стрелочные функции везде для чистоты и краткости кода, как в примере выше с moreThan20: Default parameters в ES6 позволяют устанавливать параметры по умолчанию при создании функций. Рассмотрим пример, чтобы понять насколько это полезно. Создадим функцию, которая оглашает имя игрока команды. Если написать эту функцию на ES5, то получится: На первый взгляд, кажется, что с кодом всё в порядке. Однако, вдруг необходимо будет огласить игрока, который не состоит ни в одной из команд? Текущий код просто не справиться с задачей, если пропустить teamName: Очевидно, undefined — это не название команды. Если игрок не относится ни к одной из команд, то оглашение Zell Liew, unaffiliated будет иметь больше смысла, чем Zell Liew, undefined. Согласен? Для того чтобы announcePlayer оглашала Zell Liew, unaffiliated, возможно, как вариант, передать строку unaffiliated вместо teamName: Хотя такой подход работает, но лучше внести улучшение в announcePlayer через проверку наличия teamName. В ES5 отрефакторенный код стал бы таким: Или при знании тернарных операторов возможен выбор более короткого варианта: В ES6 с помощью параметров по умолчанию можно добавлять знак равенства = всякий раз при указании параметра. При применении такого подхода ES6 автоматически присваивает значение по умолчанию, когда параметр не определён. Так в коде ниже, когда teamName не определён, то teamName принимает значение по умолчанию unaffiliated. Удобно, не правда ли? Обратим внимание на еще один момент. Если требуется активировать значение по умолчанию, можно передать undefined вручную. Такая ручная передача undefined оказывается к месту, когда параметр по умолчанию не является последним аргументом функции. Выше рассмотрено то, что требуется знать о параметрах по умолчанию. Достаточно просто и очень удобно.