javascript对象,自引用问题

时间:2011-03-17 13:26:26

标签: javascript oop methods

我刚开始在javascript中使用oop,我遇到了一些问题,试图从另一个方法中访问一个方法。

这是我的代码:

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方法。 我无法找到真正的解决方案。 最终我找到了How to call a method inside a javascript object 答案似乎是我需要保护这个引用,如: 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);
}

}

2 个答案:

答案 0 :(得分:14)

执行此操作时:

setTimeout(this.update, 10);
正确地将对“update”函数的引用传递给系统,但是当浏览器实际上稍后调用该函数时,它将不知道this应该是什么是。您可以做的是以下内容:

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

这将确保在调用“update”时调用它,并将this正确设置为对象的引用。

与其他语言不同,函数最初被定义为对象的属性这一事实本身并不将函数绑定到该对象。以同样的方式,如果你有一个具有属性的对象,这是一个简单的数字:

   maxLength: 25,

值“25”与对象没有任何关系;这只是一个价值。在JavaScript中,函数也只是值。因此,只要以某种“特殊”方式调用函数,程序员就有责任确保将this设置为适当的东西。

答案 1 :(得分:0)

您的问题是您使用对象文字而不是实例化对象

尝试这样做:

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();