Возможно, вы не знаете, что это одно из основных различий между обычными функциями и стрелочными функциями ES6 в JavaScript.

Когда я был в учебном лагере по программированию, изучая JavaScript и ES6, казалось, что у всех в классе была некоторая путаница по поводу обычных объявлений функций и новых объявлений функций стрелок ES6. Общие вопросы, которые мы включили:

  • Когда нам следует использовать обычные функции или стрелочные функции?
  • В чем разница между обычными функциями и стрелочными функциями?
  • Можем ли мы использовать одно или другое во всех ситуациях для единообразия?

Проведя небольшое исследование, я обнаружил, что обычные функции и стрелочные функции фактически не взаимозаменяемы в определенных обстоятельствах. Помимо синтаксиса, обычные функции и стрелочные функции имеют еще одно важное отличие: способ связывания ключевого слова this в JavaScript.

Давайте посмотрим на очень простой пример. Предположим, у нас есть простой объект JavaScript:

У нас есть print метод на obj1, который записывает строку в консоль. В результате мы ожидали, что this в методе print относится к самому obj1.

Теперь давайте создадим еще один объект немного другим print методом:

Теперь метод print регистрирует результирующую строку только через одну секунду из-за setTimeout. Но почему он регистрирует undefined is undefined вместо Object 2 is blue?

Ответ заключается в объявлении функции, которое мы передали как обратный вызов для setTimeout. Обычное объявление функции создает область действия, и любое использование this внутри функции будет относиться к непосредственному родительскому объекту, которому принадлежит функция.

В нашем фрагменте кода в строке 5 анонимная функция, объявленная с использованием обычного объявления функции, передается как обратный вызов для setTimeout. Затем два this в строке 6 будут ссылаться на объект, которому принадлежит метод setTimeout, который оказывается объектом window.

Поскольку свойства fullName и color не существуют в объекте window, результирующая строка возвращает undefined is undefined.

Как мы можем сделать так, чтобы два this в строке 6 вместо этого ссылались на obj2? На этот раз давайте объявим функцию обратного вызова в строке 5, используя объявление функции стрелки ES6:

Оно работает! Так какова теория этого изменения?

Что ж, оказывается, что объявление функции стрелки создает то, что мы называем лексической областью действия. Это означает, что два this в строке 6 будут ссылаться не на их непосредственный родительский объект, а на вызывающего, который вызвал функцию, которая их содержит.

В строке 11, когда obj2 вызывает метод print, любые this, заключенные внутри стрелочных функций в методе print, будут ссылаться на obj2.

Заключение

Я надеюсь, что эта статья хорошо объяснила эти концепции и помогла облегчить некоторую путаницу, которую испытала наша когорта во время учебного лагеря. Ключевое слово this в JavaScript - это отдельная тема, о которой много говорят в Интернете, но MDN doc здесь является хорошей отправной точкой.