В данный момент я пытаюсь понять функции стрелок.
Я знаю, что с функциями стрелок область видимости немного отличается. Тем не менее, я все еще немного смущен тем, как все это работает.
Вот пример, который я не очень хорошо понимаю.
// 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
относится к контексту, в котором используется код написано (также известный как «лексическая привязка»). В функциях es5 this
относится к контексту, из которого код называется. Итак, в этом случае, когда вы хотите, чтобы this
ссылалась на obj
, вам нужно вызвать bind.
Актуально, если не повторяется: stackoverflow.com/q/24900875/497418
В первом примере, если вы не будете использовать 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
. Thethis
value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching forthis
which is not present in current scope they end up findingthis
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();
this
вconsole.info(this.id);
относится к объекту счетчика.->
Нет относится кobj
.