Что такое es6 javascript
Обзор базовых возможностей ES6
JavaScript сильно изменился за последние годы. Вот 12 новых возможностей, которые можно начать использовать уже сегодня!
История
Новые добавления в язык называются ECMAScript 6. Или ES6 или ES2015+.
С момента появления в 1995, JavaScript развивался медленно. Новые возможности добавлялись каждые несколько лет. ECMAScript появился в 1997, его целью было направить развитие JavaScript в нужное русло. Выходили новые версии – ES3, ES5, ES6 и так далее.
Как видите, между версиями ES3, ES5 и ES6 есть пропуски длиной в 10 и 6 лет. Новая модель – делать маленькие изменения каждый год. Вместо того, чтобы накопить огромное количество изменений и выпустить их все за раз, как это было с ES6.
Browsers Support
Все современные браузеры и среды исполнения уже поддерживают ES6!
Chrome, MS Edge, Firefox, Safari, Node и многие другие системы имеют встроенную поддержку большинства возможностей JavaScript ES6. Так что, все из этого пособия можно использовать прямо сейчас.
Главные возможности ES6
Все сниппеты можно вставлять в консоль браузера и запускать.
Block scope variables
Проблема var в том, что переменная «протекает» в другие блоки кода, такие как циклы for или блоки условий if :
ES6 спешит на помощь:
Изменив var на let мы откорректировали поведение. Если блок if не вызывается, то переменная x не переопределяется.
IIFE (immediately invoked function expression)
Давайте сначала рассмотрим пример:
Как видите, private протекает наружу. Нужно использовать IIFE (immediately-invoked function expression):
В ES6 не нужно использовать IIFE, достаточно использовать блоки и let :
Const
Можно также использовать const если переменная не должна изменяться.
Template Literals
Не нужно больше делать вложенную конкатенацию, можно использовать шаблоны. Посмотрите:
Multi-line strings
Не нужно больше конкатенировать строки с + \n :
В ES6 можно снова использовать бэктики:
Оба блока кода генерируют одинаковый результат
Destructuring Assignment
ES6 destructing – полезная и лаконичная штука. Посмотрите на примеры:
Получение элемента из массива
Обмен значениями
Деструктуризация нескольких возвращаемых значений
В строке 3 можно вернуть в виде массива:
но вызывающему коду придется знать о порядке данных.
С ES6 вызывающий выбирает только нужные данные (строка 6):
Заметка: В строке 3 содержатся другие возможности ES6. Можно сократить < left: left >до < left >. Смотрите, насколько это лаконичнее по сравнению с версией ES5. Круто же?
Деструктуризация и сопоставление параметров
То же самое (но короче):
Глубокое сопоставление
То же самое (но короче):
Это также называют деструктуризацией объекта (object destructing).
Как видите, деструктуризация может быть очень полезной и может подталкивать к улучшению стиля кодирования.
Классы и объекты
Каждый объект в JavaScript имеет прототип, который является другим объектом. Все объекты в JavaScript наследуют методы и свойства от своего прототипа.
В ES5 объектно-ориентированное программирование достигалось с помощью функций-конструкторов. Они создавали объекты следующим образом:
Оба стиля (ES5/6) дают одинаковый результат.
Наследование
В ES5 придется немного поработать с прототипным наследованием.
Не будем вдаваться в детали, но заметьте несколько деталей:
Посмотрите, насколько лучше выглядит код на ES6 по сравнению с ES5. И они делают одно и то же! Win!
Нативные промисы
Переходим от callback hell к промисам (promises)
Одна функция принимает callback чтобы запустить его после завершения. Нам нужно запустить ее дважды, одну за другой. Поэтому приходится вызывать printAfterTimeout во второй раз в коллбеке.
Все становится совсем плохо когда нужно добавить третий или четвертый коллбек. Давайте посмотрим, что можно сделать с промисами:
С помощью then можно обойтись без вложенных функций.
Стрелочные функции
В ES5 обычные определения функций не исчезли, но был добавлен новый формат – стрелочные функции.
В ES5 есть проблемы с this :
For…of
От for переходим к forEach а потом к for. of :
ES6 for…of позволяет использовать итераторы
Параметры по умолчанию
От проверки параметров переходим к параметрам по умолчанию. Вы делали что-нибудь такое раньше?
Скорее всего да. Это распространенный паттерн проверки наличия значения переменной. Но тут есть некоторые проблемы:
Если параметр по умолчанию это булева переменная или если задать значение 0, то ничего не получится. Почему? Расскажу после этого примера с ES6 😉
В ES6 все получается лучше с меньшим количеством кода:
С проверкой на undefined все работает как нужно.
Rest-параметры
От аргументов к rest-параметрам и операции spread.
В ES5 работать с переменным количеством аргументов неудобно.
Операция Spread
В ES6 используем spread:
Мы также перешли от concat к spread’у:
Заключение
JavaScript сильно изменился. Эта статья покрывает только базовые возможности, о которых должен знать каждый разработчик.
ECMAScript 6
Границы моего языка олицетворяют границы моего мира.
— Людвиг Витгенштейн
Последние несколько месяцев я пишу только ECMAScript 6 код, воспользовавшись трансформацией [1] в поддерживаемые в настоящее время версии JavaScript.
ECMAScript 6, далее ES6 и ранее ES.next, является последней версией спецификации. По состоянию на август 2014 новые возможности не обсуждаются, но детали и крайние случаи до сих пор уточняются. Ожидается, что стандарт будет завершен и опубликован в середине 2015 года.
Принятие ES6 одновременно привело к повышению производительности (что делает мой код более лаконичным) и ликвидации целого класса ошибок путем устранения распространённых подводных камней JavaScript.
Это должно быть достаточно очевидным для вас, если вы использовали CoffeeScript, который сосредотачивается на хороших частях JS и скрывает плохие. ES6 смог принять на столько много инноваций из CoffeeScript, что некоторые даже ставят под сомнение дальнейшее развитие последнего.
For all intents and purposes, JavaScript has merged CoffeeScript into master. I call that a victory for making things and trying them out.
Вместо того, чтобы сделать тщательный анализ новых возможностей я расскажу о наиболее интересных из них. Чтобы стимулировать разработчиков обновляться, новые языки и фреймворки должны (1) иметь убедительную историю совместимости и (2) предлагать вам достаточно большую морковку.
# Синтаксис модулей
ES6 знакомит с синтаксисом для определения модулей и объявления зависимостей. Я подчеркиваю слово синтаксис потому что ES6 не имеет отношение к фактической реализации того, как модули будут выбраны или загружены.
Это еще более укрепляет взаимодействие между различными контекстами, в которых может выполняться JavaScript.
Рассмотрим в качестве примера простую задачу написания многоразового использования CRC32 в JavaScript.
До сих пор, не существовало никаких рекомендаций о том, как на самом деле решить эту задачу. Общий подход это объявить функцию:
С оговоркой, конечно же, что она вводит единое фиксированное глобальное имя, на которое другие части кода будут должны ссылаться. И с точки зрения кода, который использует crc32 функцию, нет способа объявить зависимость. Как только функция была объявлена, она будет существовать до тех пор, пока код не будет интерпретирован.
Типичный сценарий, чтобы проиллюстрировать эти недостатки это генерация связки модулей для браузера, с помощью таких инструментов, как browserify или webpack. Они еще находятся в зачаточном состоянии, потому что они воспринимают require() как синтаксис, эффективно избавляя себя от свойственного им динамизма.
Приведенный пример не подлежит статическому анализу, поэтому если вы попытаетесь транспортировать этот код в браузер, то он сломается:
Другими словами, алгоритм упаковщика не может знать заранее, что означает woot().
ES6 ввел правильный набор ограничений, учитывая большинство существующих вариантов использования, черпая вдохновение из самых неформально-существующих специальных модульных систем, как jQuery $.
Синтаксис требует некоторого привыкания. Наиболее распространенный шаблон для определения зависимостей удивительно непрактичен.
последний считается именованным экспортом и требует синтаксис в конструкции import:
Другими словами, самая простая (и, пожалуй, наиболее желательная) форма определения модуля требует дополнительное ключевое слово default. Или в случае его отсутствия, использование при импорте.
# Деструктуризация
Одним из наиболее распространенных шаблонов, возникших в современном JavaScript коде является использование вариантных объектов.
Такая практика широко используется в новых браузерных API, например в WHATWG fetch (современная замена XMLHttpRequest):
Повсеместное принятие этой модели эффективно препятствует падению экосистемы JavaScript в логическую ловушку.
Если принять, что API принимает обычные аргументы, а не объект с параметрами, то вызов fetch превращается в задачу запоминания порядка аргументов и ввода ключевого слова null в нужное место.
Со стороны реализации, однако, это не выглядит так же красиво. Глядя на объявление функции, ее сигнатура больше не описывает входные возможности:
Обычно это сопровождается ручной установкой значений по-умолчанию локальным переменным:
И к сожалению для нас, несмотря на свою распространенность, практика использования || фактически привносит трудно выявляемые ошибки. Например, в этом случае мы не допускаем того, что opts.body может быть 0, поэтому надежный код скорее всего будет выглядеть так:
Благодаря деструктуризации мы можем сразу четко определить параметры, правильно задать значения по умолчанию и выставить их в локальной области видимости:
Собственно, значение по умолчанию можно применить и ко всему объекту с параметрами:
Вы также можете деструктурировать оператор присваивания:
Это напоминает мне о выразительности, предоставленные with, но без магии или негативных последствий.
# Новые соглашения
Некоторые части языка были полностью заменены лучшими альтернативами, что быстро станет новым стандартом того, как вы пишете JavaScript.
Я расскажу о некоторых из них.
# let/const вместо var
Вместо того, чтобы писать var x = y скорее всего вы будете писать let x = y. let позволяет объявлять переменные с блочной областью видимости:
Это особенно полезно для for или while циклов:
Используйте const, если вы хотите обеспечить неизменяемость с той же семантикой, как и let.
# строковые шаблоны вместо конкатенации
В связи с отсутствием sprintf или подобными утилитами в стандартной библиотеки JavaScript, составление строк всегда было более болезненным, чем следовало бы.
Строковые шаблоны сделали встраивание выражений в строки тривиальной операцией, также как и поддержку нескольких линий. Просто замените ‘ на `
# классы вместо прототипов
Определение класса было громоздкой операцией и требовало глубокого знания внутреннего устройства языка. Даже несмотря на то, что, польза понимания внутреннего устройства очевидна, порог входа для новичков был неоправданно высоким.
class предлагает синтаксический сахар для определения функции конструктора, методов прототипа и геттеров / сеттеров. Он также реализует прототипное наследование со встроенным синтаксисом (без дополнительных библиотек или модулей).
Я изначально был удивлен, узнав, классы не всплывают (hoisted) (объяснение тут). Поэтому вы должны думать о них, переводя в var A = function()<> в противоположность function A()<>.
# ()=> вместо function
Не только потому что (x, y) => <> короче написать, чем function (x,y) <>, но поведение this в теле функции, скорее всего, будет ссылаться на то, что вы хотите.
Так называемые функции “толстые стрелки” лексически связанны. Рассмотрим пример метода внутри класса, который запускает два таймера:
К ужасу новичков, первый таймер (с использованием function) выведет «undefined». А вот второй правильно выведет name.
# Первоклассная поддержка async I/O
Асинхронное выполнение кода сопровождало нас в течение почти всей истории языка. setTimeout, в конце концов, был введен примерно в то время, когда вышел JavaScript 1.0.
Но, пожалуй, язык не поддерживает асинхронность на самом деле. Возвращаемое значение вызовов функций, которые запланированы “выполниться в будущем” обычно равны undefined или в случае с setTimeout — Number.
Введение Promise позволило заполнить очень большую пропасть в совместимости и композиции.
С одной стороны, вы найдете API более предсказуемым. В качестве теста, рассмотрим новое fetch API. Как это работает за сигнатурой, которую мы только что описали? Вы угадали. Оно возвращает Promise.
Если Вы использовали Node.JS в прошлом, вы знаете, что есть неформальная договоренность о том, что обратные вызовы следуют сигнатуре:
Также неофициально указана идея о том, что обратные вызовы будут вызываться только один раз. И null будет значение в случае отсутствия ошибок (а не undefined или false). За исключением, возможно, это не всегда так.
# Вперед к будущему
ES6 набирает немалые обороты в экосистеме. Chrome и io.js уже добавили некоторый функционал из ES6. Много уже было написано об этом.
Но стоит отметить то, что эта популярность была во многом обусловлена наличием утилит для трансформации, а не фактической поддержкой. Отличные инструменты появились, для того чтобы включить трансформацию и эмуляцию ES6, и браузеры со временем добавили поддержку отладки кода и отлова ошибок (с помощью карт кода).
Эволюция языка и его предполагаемый функционал, опережают реализацию. Как говорилось выше, Promise — по-настоящему интересен как самостоятельный блок, который предлагает решение проблемы callback hell раз и навсегда.
Стандарт ES7 предлагает сделать это путем введения возможности ожидания (async) объекта Promise:
Хотя эта спецификация обсуждается уже давно, тот же инструмент, который компилирует ES6 в ES5 уже реализовал это.
Предстоит еще много работы для того, чтобы убедиться, что процесс принятия нового синтаксиса языка и API становится еще более лишенным странностей для тех, кто только приступает к работе.
Но одно можно сказать точно: мы должны принять это будущее.
Сноски:
1. ^ я использую слово “трасформация” в статье, чтобы объяснить компиляцию исходного кода в исходный код в JavaScript. Но значение этого термина технически спорно.
Руководство по JavaScript, часть 8: обзор возможностей стандарта ES6
Сегодня, в восьмой части перевода руководства по JavaScript, мы сделаем обзор возможностей языка, которые появились в нём после выхода стандарта ES6. Мы, так или иначе, сталкивались со многими из этих возможностей ранее, где-то останавливаясь на них подробнее, где-то принимая как нечто само собой разумеющееся. Этот раздел руководства призван, наряду с раскрытием некоторых тем, которых мы ранее не касались, упорядочить знания начинающего разработчика в области современного JavaScript.
О стандарте ES6
Стандарт ES6, который правильнее было бы называть ES2015 или ECMAScript 2015 (это — его официальные наименования, хотя все называют его ES6), появился через 4 года после выхода предыдущего стандарта — ES5.1. На разработку всего того, что вошло в стандарт ES5.1, ушло около десяти лет. В наши дни всё то, что появилось в этом стандарте, превратилось в привычные инструменты JS-разработчика. Надо отметить, что ES6 внёс в язык серьёзнейшие изменения (сохраняя обратную совместимость с его предыдущими версиями). Для того чтобы оценить масштаб этих изменений, можно отметить, что размер документа, описывающего стандарт ES5, составляет примерно 250 страниц, а стандарт ES6 описывается в документе, состоящем уже из приблизительно 600 страниц.
В перечень наиболее важных новшеств стандарта ES2015 можно включить следующие:
Стрелочные функции
Стрелочные функции изменили внешний вид и особенности работы JavaScript-кода. С точки зрения внешнего вида их использование делает объявления функций короче и проще. Вот объявление обычной функции.
А вот практически такая же (хотя и не полностью аналогичная вышеобъявленной) стрелочная функция.
Если тело стрелочной функции состоит лишь из одной строки, результат выполнения которой нужно из этой функции вернуть, то записывается она ещё короче.
Если стрелочная функция принимает лишь один параметр, записать её можно следующим образом.
Надо отметить, что с появлением стрелочных функций обычные функции никуда не делись, их всё так же можно использовать в коде, работают они так же, как и прежде.
Особенности ключевого слова this в стрелочных функциях
Промисы
JavaScript-разработчики использовали промисы и до появления стандарта ES2015, применяя для этого различные библиотеки (например — jQuery, q, deferred.js, vow). Это говорит о важности и востребованности данного механизма. Разные библиотеки реализуют его по-разному, появление стандарта в этой области можно считать весьма позитивным фактом.
Вот код, написанный с использованием функций обратного вызова (коллбэков).
С использованием промисов это можно переписать следующим образом.
Генераторы
Генераторы — это особые функции, которые могут приостанавливать собственное выполнение и возобновлять его. Это позволяет, пока генератор находится в состоянии ожидания, выполняться другому коду.
Генератор самостоятельно принимает решение о том, что ему нужно приостановиться и позволить другому коду, «ожидающему» своей очереди, выполниться. При этом у генератора есть возможность продолжить своё выполнение после того, как та операция, результатов выполнения которой он ждёт, окажется выполненной.
Рассмотрим пример, иллюстрирующий особенности работы генераторов. Вот сам генератор.
Такой командой мы его инициализируем.
Затем мы обращаемся к его итератору.
Эта команда запускает итератор, она возвращает такой объект.
В ответ на это итератор возвращает нам следующий объект.
В ответ получаем следующий объект.
Ключевые слова let и const
Классы
Сложилось так, что JavaScript был единственным чрезвычайно широко распространённым языком, использующим модель прототипного наследования. Программисты, переходящие на JS с языков, реализующих механизм наследования, основанный на классах, чувствовали себя в такой среде неуютно. Стандарт ES2015 ввёл в JavaScript поддержку классов. Это, по сути, «синтаксический сахар» вокруг внутренних механизмов JS, использующих прототипы. Однако это влияет на то, как именно пишут JS-приложения.
Теперь механизмы наследования в JavaScript выглядят как аналогичные механизмы в других объектно-ориентированных языках.
▍Конструктор класса
▍Ключевое слово super
Ключевое слово super позволяет обращаться к родительскому классу из классов-потомков.
▍Геттеры и сеттеры
Геттер для свойства можно задать следующим образом.
Сеттер можно описать так, как показано ниже.
С геттерами и сеттерами работают так, как будто они представляют собой не функции, а обычные свойства объектов.
Модули
До появления стандарта ES2015 существовало несколько конкурирующих подходов к работе с модулями. В частности, речь идёт о технологиях RequireJS и CommonJS. Такая ситуация приводила к разногласиям в сообществе JS-разработчиков.
В наши дни, благодаря стандартизации модулей в ES2015, ситуация постепенно нормализуется.
▍Импорт модулей
▍Экспорт модулей
▍Шаблонные литералы
Шаблонные литералы представляют собой новый способ описания строк в JavaScript. Вот как это выглядит.
Вот пример посложнее, иллюстрирующий возможность вычисления любых выражений и подстановки их результатов в строку.
Благодаря использованию шаблонных литералов гораздо легче стало объявлять многострочные строки.
Сравните это с тем, что приходилось делать для описания многострочных строк при использовании возможностей, имевшихся в языке до ES2015.
Параметры функций, задаваемые по умолчанию
Теперь функции поддерживают параметры, используемые по умолчанию — в том случае, если при вызове функций им не передаются соответствующие аргументы.
Оператор spread
Вот как на основании этого массива создать новый массив.
Вот как создать копию массива.
Этот оператор работает и с объектами. Например — вот как с его помощью можно клонировать объект.
Применив оператор spread к строке, можно преобразовать её в массив, в каждом элементе которого содержится один символ из этой строки.
Этот оператор, помимо вышеописанных вариантов его применения, удобно использовать при вызове функций, ожидающих обычный список аргументов, с передачей им массива с этими аргументами.
Деструктурирующее присваивание
Техника деструктурирующего присваивания позволяет, например, взять объект, извлечь из него некоторые значения и поместить их в именованные переменные или константы.
Деструктурирующее присваивание подходит и для работы с массивами.
Расширение возможностей объектных литералов
В ES2015 значительно расширены возможности описания объектов с помощью объектных литералов.
▍Упрощение включения в объекты переменных
Раньше, чтобы назначить какую-нибудь переменную свойством объекта, надо было пользоваться следующей конструкцией.
Теперь то же самое можно сделать так.
▍Прототипы
Прототип объекта теперь можно задать с помощью следующей конструкции.
▍Ключевое слово super
С использованием ключевого слова super объекты могут обращаться к объектам-прототипам. Например — для вызова их методов, имеющих такие же имена, как методы самих этих объектов.
▍Вычисляемые имена свойств
Вычисляемые имена свойств формируются на этапе создания объекта.
Цикл for. of
Структуры данных Map и Set
Итоги
Сегодня мы сделали обзор возможностей стандарта ES2015, которые чрезвычайно сильно повлияли на современное состояние языка. Нашей следующей темой будут особенности стандартов ES2016, ES2017 и ES2018.
Уважаемые читатели! Какие новшества стандарта ES6 кажутся вам наиболее полезными?
Введение в часто используемые особенности ES6. Часть 1
Данная публикация является переводом статьи «Introduction to commonly used ES6 features» под авторством Zell Liew, размещенного здесь. Перевод разделён на 2 части. Перевод 2-ой части находится здесь.
JavaScript серьезно развился в последние несколько лет. Если вы изучаете язык в 2017 году и при этом не касались ECMAScript 6 (ES6), то упускаете легкий способ читать и писать на нём.
Не волнуйтесь, если вы еще не знаток языка. От вас не требуется превосходно знать его, чтобы пользоваться преимуществами «бонусов», добавленных в ES6. В этой статье хотел бы поделиться восемью особенностями ES6, которые использую каждый день как разработчик, что поможет вам легче погрузиться в новый синтаксис.
Примечание переводчика: в статье представлены семь особенностей («Промисы» рассматриваются в отдельной статье).
Список особенностей ES6
Во-первых, ES6 — это огромное обновление JavaScript. Здесь приведён большой перечень особенностей (спасибо, Luke Hoban), если интересно, какие нововведения появились:
Не стоит пугаться такого большого списка особенностей ES6. От вас не требуется знать все сразу. Далее поделюсь восемью особенностями, которые применяю каждый день. К ним относятся:
Кстати, браузеры очень хорошо поддерживают ES6. Почти все особенности обеспечиваются нативно, если пишете код для последних версий браузеров (Edge, последние версии FF, Chrome и Safari).
Для написания кода на ES6 не нужен такой инструмент, как Webpack. При отсутствии поддержки браузером всегда можно обратиться к полифиллам, созданными сообществом. Достаточно погуглить.
Итак, приступим к первой особенности.
Let и const
Let vs var
Однако, обратное не верно. Если переменную объявить в функции, то будет невозможно использовать её снаружи функции.
Так, можем говорить, что у var область видимости «функциональная». Это означает, что всякий раз, когда переменная объявляется с помощью var в функции, она будет существовать только в пределах функции.
Если переменная создается снаружи функции, она будет существовать во внешней области видимости.
Подождите, но что же значит «блок»?
Блоком в JavaScript называется то, что находится внутри пары фигурных скобок. Ниже примеры блоков:
Разница между переменными, объявленными «блочно» и «функционально», огромна. При объявлении переменной «функционально» в дальнейшем можно случайно переписать значение этой переменной. Ниже пример:
Этот пример показывает, что значение me становится ‘Sleepy head’ после выполнения кода внутри if блока. Такой пример, скорее всего, не вызовет какие-либо проблемы, т.к. вряд ли будут объявляться переменные с одинаковым именем.
Какой результат можно ожидать при выполнения этого кода? Ниже то, что в действительности произойдет:
i будет четыре раза выведена со значением «5» в функции-таймере
Как i получил значение «5» четыре раза внутри таймера? Всё из-за того, что var определяет переменную «функционально», и значение i становится равным «4» еще до того, как таймер начнёт выполняться.
i правильно выводится как 1, 2, 3 и 4
Кстати, это называется замыканием.
i правильно выводится как 1, 2, 3 и 4
Как можно увидеть, «блочно» объявленные переменные, обходя недостатки «функционально» объявленных переменных, намного упрощают разработку. Для упрощения советую с этого момента использовать let вместо var каждый раз, когда необходимо объявлять переменные в JavaScript.
Let vs const
Раз const нельзя изменить, то можно использовать для переменных, которые не будут меняться.
Допустим, на сайте имеется кнопка, которая запускает модальное окно, и мы знаем, что такая кнопка одна и изменяться не будет. В этом случае, используем const :
Далее рассмотрим стрелочные функции.
Стрелочные функции
Стрелочные функции довольно удобны, т.к. с их помощью можно сократить код, тем самым уменьшив места, где могут скрываться ошибки. Также код, написанный на них, легче понимать, если вы знакомы с их синтаксисом.
Рассмотрим стрелочные функции поближе, чтобы научиться распознавать и использовать их.
Подробнее о стрелочных функциях
Сначала обратим внимание на создание функций.
В JavaScript, вероятно, привычно создавать функции следующим способом:
Второй способ создания функций связан с написанием анонимной функции и её присвоением переменной. Для создания анонимной функции необходимо вынести её название из объявления функции.
Третий способ создания функций заключается в том, чтобы передавать их напрямую как аргумент в другую функцию или в метод. Этот способ является наиболее распространенным для анонимных функций. Ниже пример:
Поскольку стрелочные функции в ES6 представляют собой сокращенное обозначение анонимных функций, их можно внедрять везде, где создаются анонимные функции.
Ниже то, как это выглядит:
Заметили сходство? По существу, удаляют ключевое слово function и заменяют стрелкой => в немного другом месте.
Так в чём же заключается суть стрелочных функций? Только в замене function на =>?
На самом деле дело не только в замене function на =>. Синтаксис стрелочной функции может быть изменён в зависимости от двух факторов:
Все ниже перечисленные примеры являются допустимыми стрелочными функциями.
Под 2-ым фактором понимается необходимость неявного возврата. Стрелочные функции, по умолчанию, автоматически создают ключевое слово return, если код занимает одну строку и не обернут в фигурные скобки <>.
Итак, ниже два равнозначных примера:
В заключение отмечу, стрелочные функции довольно хороши. Потратив немного времени и испытав их, можно привыкнуть к ним и везде использовать.
Лексический this
this — уникальное ключевое слово, значение которого меняется в зависимости от контекста вызова. При вызове снаружи функции this ссылается на объект Window в браузере.
При вызове this в методе объекта, оно ссылается на сам объект:
При вызове функции-конструктора this ссылается на конструируемый объект.
При использовании в обработчике события this ссылается на элемент, который запустил событие.
В стрелочных функциях this никогда не приобретает новое значение вне зависимости от того, как функция вызвана. this всегда будет иметь такое же значение, какое имеет this в окружающем стрелочную функцию коде. Кстати, лексический означает ссылающийся (связанный), из-за чего, как полагаю, лексический this и получил своё название.
Итак, это звучит запутанно, поэтому рассмотрим несколько реальных примеров.
Во-вторых, стрелочные функции могут не подойти для создания обработчиков событий, т.к. this больше не будет закреплен за элементом, к которому привязан обработчик события.
Такое применение особенно полезно, если необходимо добавить или удалить класс спустя некоторое время:
В заключение, используйте стрелочные функции везде для чистоты и краткости кода, как в примере выше с moreThan20 :
Параметры по умолчанию
Default parameters в ES6 позволяют устанавливать параметры по умолчанию при создании функций. Рассмотрим пример, чтобы понять насколько это полезно.
Создадим функцию, которая оглашает имя игрока команды. Если написать эту функцию на ES5, то получится:
На первый взгляд, кажется, что с кодом всё в порядке. Однако, вдруг необходимо будет огласить игрока, который не состоит ни в одной из команд?
Текущий код просто не справиться с задачей, если пропустить teamName :
Очевидно, undefined — это не название команды.
В ES5 отрефакторенный код стал бы таким:
Или при знании тернарных операторов возможен выбор более короткого варианта:
В ES6 с помощью параметров по умолчанию можно добавлять знак равенства = всякий раз при указании параметра. При применении такого подхода ES6 автоматически присваивает значение по умолчанию, когда параметр не определён.
Удобно, не правда ли?
Обратим внимание на еще один момент. Если требуется активировать значение по умолчанию, можно передать undefined вручную. Такая ручная передача undefined оказывается к месту, когда параметр по умолчанию не является последним аргументом функции.
Выше рассмотрено то, что требуется знать о параметрах по умолчанию. Достаточно просто и очень удобно.