Объект 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();