стрелочные функции [дубликат]

235
02 октября 2018, 18:50

На данный вопрос уже ответили:

  • Потеря контекста вызова 5 ответов

При выводе на консоль, в obj1 свойство this.name не отображается. Как правильно сделать привязку данных, подскажите? Во втором obj2 использую стрелочную функцию, все отображается (стрелочные функции не имеют своего this). В третьем obj3 ошибка

Cannot read property 'forEach' of undefined

Можно ли свойством объекта делать стрелочную функцию? Спасибо.

window.addEventListener('load', function () {
 let obj1 = {
  name: 'value',
  numbers: [1, 2, 3],
  fun1: function () {
   this.numbers.forEach(function (value, index, array) {
    console.log(this.name + ' ' + value);
   })
  }
 };
 obj1.fun1();
 let obj2 = {
  name: 'value',
  numbers: [4, 5, 6],
  fun1: function () {
   this.numbers.forEach((value, index, array) => {
    console.log(this.name + ' ' + value);
   })
  }
 };
 obj2.fun1();
 let obj3 = {
  name: 'value',
  numbers: [7, 8, 9],
  fun1: () => {
   this.numbers.forEach((value, index, array) => {
    console.log(this.name + ' ' + value);
   })
  }
 };
 obj3.fun1();
});

Answer 1

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

window.data = 'Global data'; 
let test = { 
  data: 'Object data', 
  method() { 
    console.log(this.data); 
  }, 
  func: () => console.log(this.data) 
} 
 
test.method(); // Object data 
 
test.func(); // Global data 
 
let test2 = { 
  data: 'Test2 data', 
  method() { 
    test.func2 = () => console.log(this.data); 
  } 
}; 
 
test2.method(); // в этом вызове this==test2 
test.func2(); // Поэтому: Test2 data

В obj1 же, напротив. Функция обратного вызова forEach вызывается с пустым контекстом. Здесь как раз полезны стрелочные функции для доступа к внешнему this.
Разумеется, Вы вольны сохранить this любым другим способом:

let obj1 = { 
  name: 'value', 
  numbers: [1, 2, 3], 
  f1: function () { 
   this.numbers.forEach((value, index, array) => { 
    console.log(this.name, value, 'arrow'); 
   }) 
  }, 
  f2: function() { 
   this.numbers.forEach(function(value, index, array){ 
    console.log(this.name, value, 'bind'); 
   }.bind(this)) 
  }, 
  f3: function() { 
   let that = this; 
   this.numbers.forEach(function(value, index, array){ 
    console.log(that.name, value, 'variable'); 
   }); 
  }, 
  f4: function() { 
   this.numbers.forEach(function(value, index, array){ 
    console.log(this.name, value, 'forEach thisArg'); 
   }, this); 
  } 
 }; 
  
 obj1.f1(); 
 obj1.f2(); 
 obj1.f3(); 
 obj1.f4();

READ ALSO
Порядок загрузки скрипта в JS

Порядок загрузки скрипта в JS

Почитал уже несколько подобных тем и официальную документацию и все равно не понялЕсть вот такой код

149
Дополнительное экранирование js

Дополнительное экранирование js

Есть поле textareaВ это поле юзер может вставлять любые данные

192
Автоматический вход в приложение firebase

Автоматический вход в приложение firebase

Приветсвую всех, есть web-приложение построенное на Vue + FirebaseВопрос заключается в том, как происходит автоматический вход в приложение после...

188
Если есть span c классом добавить родителю class (JS) [дубликат]

Если есть span c классом добавить родителю class (JS) [дубликат]

Данный вопрос уже был задан и имеет решение:

196