Может ли кто-нибудь объяснить функции стрелок? (ES6)

В данный момент я пытаюсь понять функции стрелок.

Я знаю, что с функциями стрелок область видимости немного отличается. Тем не менее, я все еще немного смущен тем, как все это работает.

Вот пример, который я не очень хорошо понимаю.

// ES5
var obj = {
  id: 42,
  counter: function counter() {
    setTimeout(function() {
      console.info(this.id);
    }.bind(this), 1000);
  }
};

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

// ES6
var obj = {
  id: 42,
  counter: function counter() {
    setTimeout(() => {
      console.info(this.id);
    }, 1000);
  }
};

Глядя на это, мне кажется, что все дело в уровнях. Пожалуйста, поправьте меня, если я ошибаюсь, но с ES5 мы бы использовали метод .bind() в этом случае, потому что без него он будет возвращаться как undefined. Я предполагаю, что это связано с тем, что в этом случае ключевое слово this в console.info(this.id); относится к объекту counter и по умолчанию не может найти id объекта obj.

Немного запутанно, но я думаю, что это все. Теперь, с функциями стрелок, я не уверен, почему console.info(this.id); будет работать. Означает ли это, что пока он находится в одном блоке кода, его можно использовать?

Большая признательность!

Ключевое слово this в console.info(this.id); относится к объекту счетчика.->Нет относится к obj.
Ele 08.04.2019 23:03

В стрелочных функциях this относится к контексту, в котором используется код написано (также известный как «лексическая привязка»). В функциях es5 this относится к контексту, из которого код называется. Итак, в этом случае, когда вы хотите, чтобы this ссылалась на obj, вам нужно вызвать bind.

SoZettaSho 08.04.2019 23:07

Актуально, если не повторяется: stackoverflow.com/q/24900875/497418

zzzzBov 08.04.2019 23:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
230
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

В первом примере, если вы не будете использовать bind(), то this будет ссылаться на обратный вызов setTimeout. Поскольку вы использовали .bind(), вы изменили ссылку this на объект obj. Вот почему вы получили 42 как this.id.

Во втором примере bind() не требуется, потому что стрелочная функция не имеет собственного this, она такая же, как родительская this, поэтому в данном случае она указывает на объект obj, поэтому вы также получаете 42 как this.id

Из документы:

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope they end up finding this from its enclosing scope.

Функция стрелки делает именно то, что делает .bind(this). Оба ваших примера эквивалентны.

Как все говорят, функция стрелок ES6 не имеет this, поэтому они могут использовать this своего «родителя». Но есть еще одно отличие в ES6, которое вы не заметите: в объектах js вам не нужно использовать слово function, как показано ниже.

// ES6
var obj = {
  id: 42,
  counter() {
    setTimeout(() => {
      console.info(this.id / 7);
    }, 1000);
  }
};

console.info('start')
obj.counter();

Другие вопросы по теме