JavaScript: привязка контекста [дубликат]

286
04 мая 2017, 15:16

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

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

При выполнении этого блока кода, выведется undefined, а не 'Вася', так как setTimeout получил метод user.sayHi, но не ее контекст:

var user = {
  firstName: "Вася",
  sayHi: function() {
    alert( this.firstName );
  }
};
setTimeout(user.sayHi, 1000); // undefined (не Вася!)

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

setTimeout(function() {
  user.sayHi(); // Вася
}, 1000);

Собственно возник вопрос: почему при оборачивании вызова метода в анонимную функцию, то контекст появляется?

Answer 1

Без оборачивания в анонимную функцию this становится равен window.

var user = {
  firstName: "Вася",
  sayHi: function() {
    alert( this.firstName );
    console.log(this) // Window {}
  }
};
setTimeout(user.sayHi, 1000);

С оборачиванием this равен объекту:

var user = {
  firstName: "Вася",
  sayHi: function() {
    alert( this.firstName );
    console.log(this) // Object {firstName: "Вася"}
  }
};
setTimeout(() => user.sayHi(), 1000); 

Можно вручную установить this вызовом функции через func.call(context, arg1, arg2...)

Все дело в том, что коллбэку setTimeout передается только сама функция, без ее контекста.

Answer 2

Используйте bind;

var user = {
  firstName: "Вася",
  sayHi: function() {
    alert( this.firstName );
  }
};
setTimeout(user.sayHi.bind(user), 1000); // undefined (не Вася!)

контекст меняется лишь потому, что контекст равен (вне случая bind) тому что написано до точки перед вызываемой функцией.

  my.pretty.good.object.method();
  //               /|\
  //----------------| контекст

если до точки ничего нет, то глобальному объекту или undefined в случае "use strict";

READ ALSO
AJAX: пустой $_FILES

AJAX: пустой $_FILES

Здравствуйте! Отправляю файл на сервер (локальный: vertrigo(apache)) с помощью AJAX и drag & drop HTML5Файл записывается в папку, на страницу с AJAX возвращается...

372
Как подключиться к firebase?

Как подключиться к firebase?

При разработке приложения на Реакте появилась такая проблемаЕсть Удаленная база данных Firebase, из которой мне нужно выгружать данные

489
TypeError: Cannot set property '0' of undefined

TypeError: Cannot set property '0' of undefined

Хочу создать многомерный массив, заполненный значения двух атрибутов, чтобы вышло что-то вроде:

266
Не рисуется canvas на неактивной вкладке

Не рисуется canvas на неактивной вкладке

ЗдравствуйтеПроблема состоит в том, что когда я запускаю рисование на одной вкладке, перехожу на вторую, а через 5 (без разницы сколько) секунд...

268