этот контекст в forEach

#javascript #foreach

#javascript #foreach

Вопрос:

Я читал документацию Mozilla, но я не понимаю this , что передается в функцию. Может ли кто-нибудь подробнее объяснить использование this аргумента здесь?

 function Counter() {
  this.sum = 0;
  this.count = 0;
}

Counter.prototype.add = function(array) {
  array.forEach(function(entry) {
    this.sum  = entry;
      this.count;
  }, this); //Why is this passed here?
};

var obj = new Counter();
obj.add([2, 5, 9]);
obj.count
// 3 
obj.sum
// 16
  

Ответ №1:

Согласно документации Mozilla:

thisArg Необязательно

Значение, которое будет использоваться как this при выполнении обратного вызова.

А также:

Если thisArg параметр предоставлен forEach() , он будет передан callback при вызове для использования в качестве его this значения.В противном случае значение undefined будет передано для использования в качестве его this значения. (Курсив добавлен)

Что делает передача thisArg to forEach , так это связывает контекст. По умолчанию this in forEach является глобальным window объектом, потому undefined что используется для this . Передача контекста позволяет вам получать доступ к вещам из этого контекста.

В прототипе this есть Counter конструктор, и передача затем позволяет установить контекст, который this находится внутри forEach . Таким образом, вместо this того, чтобы находиться window внутри forEach , он находится сейчас Counter , и вы можете получить доступ к таким переменным, которые в this.sum противном случае недоступны из-за контекста.

Комментарии:

1. Большое вам спасибо

2. @JacksonXie, на самом деле, если какой- либо ответ полезен, вы должны проголосовать. Что касается ответов на вопросы, которые вы задаете, если это ответ, который вы лично использовали для решения своей проблемы, то вы должны принять его. Если это было и решение, которое вы использовали, и полезное (трудно не быть полезным, если оно решило вашу проблему), тогда вы должны принять его и проголосовать.

Ответ №2:

Поскольку функции являются автономными, ваши действия:

 function x(){
  this.test = 5
}
  

он существует только в пределах области действия функции.

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

Это аналогично использованию bind функции.

 function test(){
  this.a = 4;
  var y = function(){
    this.a  = 1;
  }.bind(this);
}
  

если бы вы не связали, например, this.a был бы неопределенным, поэтому строка: this.a = 1; была бы такой же, как если бы говорилось: this.a = undefined 1

но когда вы свяжете, он скажет: this.a = 4 1

Ответ №3:

Вы можете предотвратить изменение области видимости, используя функцию arrow в es6.

Выражение функции со стрелкой имеет более короткий синтаксис по сравнению с выражениями функций и не связывает свои собственные this , arguments, super или new.target .

 function Counter() {
  this.sum = 0;
  this.count = 0;
}

Counter.prototype.add = function(array) {
  array.forEach(entry=>{this.sum  = entry;  this.count});
};

var obj = new Counter();
obj.add([2, 5, 9]);
console.log(obj);  

Это удобно, когда альтернативные методы, доступные в es5, используются bind() для привязки this параметра или использования thisArg того, что поставляется, forEach как уже объяснялось в других ответах.

Комментарии:

1. Было бы неплохо быть немного более подробным в вашем объяснении. Ваше единственное предложение заставило бы наивного читателя задуматься, что вы имели в виду под «областью видимости» и «функцией стрелки». Другими словами, ваш ответ не стоит особняком. Для этого требуется, чтобы читатель прочитал другие ответы и немного о функциях со стрелками. Вы даже не предоставляете ссылки с дополнительными объяснениями.

2. @Makyen внес некоторые изменения, добавив дополнительные пояснения. Спасибо, что заметили 🙂