Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   теряется this (https://javascript.ru/forum/dom-window/71431-teryaetsya.html)

victornalchik 18.11.2017 11:13

теряется this
 
Здравствуйте! Возникла проблема с потерей this.
Имеется у класса контроллер метод startGame (общается к классу модели), который вызывается при нажатии кнопки.

первый вариант все отрабатывает и показывает(разовый вызов при нажатии 1- вариант), как только заношу в setInterval(для переодического вызова 2-ой), this теряется. Не знаю как решить проблему(


startGame(){

//1-ый вариант

this.matrix = this.model.createChangeMatrix(this.matrix, this.row, this.column, null, null);
return this.matrix;



//2-ой вариант

this.flagGame = setInterval(function() {
this.matrix = this.model.createChangeMatrix(this.matrix, this.row, this.column, null, null);
return this.matrix;
},1000);


}

рони 18.11.2017 11:49

victornalchik,
сохраните this в переменную, классика var that = this; ...that.matrix =

Rasy 18.11.2017 12:22

Цитата:

Сообщение от рони
сохраните this в переменную, классика var self = this; ...self.matrix =

Я как-то читал, что в self не рекомендуется сохранять. Правильнее использовать ключевое слово that

Dilettante_Pro 18.11.2017 15:16

self - ключевое слово js, ссылка на текущее окно, поэтому лучше использовать that или что угодно другое

victornalchik 18.11.2017 15:24

Большое спасибо! Помогло!

рони 18.11.2017 15:24

Rasy,
Dilettante_Pro,
ок! :)

Dilettante_Pro 18.11.2017 18:18

рони,
Бдим!:victory:

nerv_ 19.11.2017 11:00

перечислю все известные мне способы решения "детских" проблем с this. Почему детских? Потому, что разработчики со стажем знают, что this в JS -- динамический.


1) используя замыкание (об этом писали здесь выше)
function foo() {
  const that = this
  setTimeout(function () {
    console.log(that)
  })
}

2) используя привязку контекста и каррирование -- .bind()
function foo() {
  setTimeout(function () {
    console.log(this)
  }.bind(this))
}

3) явное указание контекста -- .apply() .call()
function foo() {
  console.log(this)
}

foo.call(/*ctx*/)
foo.apply(/*ctx*/)

4) используя arrow function
function foo() {
  setTimeout(_ => {
    console.log(this)
  })
}

5) используя классы TypeScript (если я правильно помню, могу ошибаться)

Aetae 20.11.2017 03:21

А можно и по-извращаться.)
Например мне нравится такой милый ленивый геттер, который заодно ещё и биндит this к функции, 2 в 1:) :
var obj = {
  bar: false,
  get foo(){
    this.bar = 2;
    delete this.foo;
    return this.foo = () => {
      this.bar *= 2;
    }
  }
}

setTimeout(obj.foo, 100);
setTimeout(()=>console.log(obj.bar), 200);
оно конечно надо не всегда, но когда совпадает - приятно.)


Часовой пояс GMT +3, время: 12:31.