Объект javascript, проблема с самоналожением

Я только начал использовать oop в javascript, и я столкнулся с некоторыми проблемами, пытаясь получить метод из другого метода.

вот код, который у меня был:

var Game = {
initialize: function () {
    if (canvas.isSupported()) {
        sprites[0] = new Player();

        this.update();
    }
},

update: function() {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
},

draw: function() {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }

    setTimeout(this.update, 10);
},

clear: function() {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
}

}

но вызов Game.update() дает ошибку, что метод draw не определен. Я не мог найти для этого реального решения. в конце концов я нашел это Как вызвать метод внутри объекта javascript где ответ, кажется, заключается в том, что мне нужно сохранить эту ссылку, например: var _this = this; но я не мог заставить это работать в буквальной нотации, поэтому я изменил код на конструктор объектов (я думаю, что он вызвал) и добавил переменную.

Затем я изменил

this.draw();

к

_this.draw();

и он работал.

хотя

this.clear();

и this.update() все те же, они никогда, казалось, не давали ошибок в первую очередь.

Может кто-нибудь объяснить, почему это? и, возможно, указать мне на лучшее решение? спасибо заранее.

Обновление

Вот что это должно быть:

var Game = function () {
var _this = this;

this.initialize = function () {
    if (canvas.isSupported()) {
        sprites[0] = new Player();

        this.update();
    }
}

this.update = function () {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
}

this.draw = function () {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }


    setTimeout(function () { _this.update(); }, 10);
}

this.clear = function () {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
}

}

Ответ 1

Когда вы это сделаете:

setTimeout(this.update, 10);

который правильно передает ссылку на вашу "обновленную" функцию в систему, но когда браузер на самом деле называет функцию позже, она не знает, что такое this. Вместо этого вы можете сделать следующее:

var me = this;
setTimeout(function() { me.update(); }, 10);

Это гарантирует, что при вызове "update" он будет вызываться с помощью this правильно задан как ссылка на ваш объект.

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

   maxLength: 25,

ну, значение "25" не будет иметь ничего общего с объектом; это просто ценность. В JavaScript функции также являются значениями. Таким образом, программист должен убедиться, что this будет задано что-то подходящее, когда функция вызывается каким-то "специальным" способом.

Ответ 2

Проблема заключается в том, что вы используете литерал объекта вместо созданного объекта

Попробуйте сделать это следующим образом:

var Game = function() {
  this.initialize = function () {
    if (canvas.isSupported()) {
      sprites[0] = new Player();
      this.update();
    }
  };
  this.update = function() {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
  };

  this.draw = function() {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }

    setTimeout(this.update, 10);
  };

  this.clear = function() {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
  };
}

теперь используйте:

 var myGame = new Game();