使用包含函数的对象创建javascript类

时间:2014-04-24 07:12:50

标签: javascript

我正在尝试创建一个javascript" class"它工作得有点好,但Engine.tile.draw并没有按预期工作。我似乎无法让它在Engine.start中运行。是不是可以创建一个对象并在其中添加一个函数,就像我一样?你们会怎么做?任何帮助表示赞赏。 :)

var EngineClass = ( function () {
    var Engine = function () {
        this.canvas = document.getElementById('game');
        this.handle = this.canvas.getContext('2d');
    };

    Engine.prototype.start = function (mapData) {
        this.tile.draw(mapData);
    };

    Engine.prototype.tile = {
      draw: function (x, y, tile) {
        this.handle.fillText(tile, x * 16, y * 16);
      };
    }

    return Engine;
})();

var Engine = new EngineClass();

3 个答案:

答案 0 :(得分:0)

使用像你这样的子对象并不是真的有效:

Engine.prototype.tile = {
  draw: function (x, y, tile) {
    this.handle.fillText(tile, x * 16, y * 16);
  };
}

问题在于,当您致电Engine.tile.draw()时,this方法中的draw()指针将设置为tile对象,而不是您的代码假设的对象(您的代码假定this指向Engine实例,而不是发生的情况。

如果您真的想要这样的子对象,那么您需要在Engine构造函数中初始化该子对象,以便每个tile对象都是唯一设置的,然后您需要添加其引擎指向tile实例数据的指针,以便在调用Engine.tile.draw()时,您可以从Engine指针获取指向this对象的相应tile实例。但是,这一切都很混乱,可能既不必要又难以做事。

您应该使用自己的实例数据创建tile自己的对象,或者将Draw方法放在Engine对象上,然后传递一些有助于它完成工作的参数。

答案 1 :(得分:0)

上面的评论说你不应该尝试强制使用原型语言的JavaScript类是正确的。

从技术上讲,这不起作用的原因是,无论何时使用点表示法(例如something.method())调用函数,都会调用函数,this绑定到左侧。点。因此,在这种情况下,当您说this.tile.draw(mapData)时,调用tile.draw函数,this作为tile对象,而不是Engine对象,因为您&# 39; d期待。

有几种方法可以解决这个问题,但最好的建议是将您的思维方式转移到JavaScript的原型系统,而不是试图强迫您使用基于类的思维模式。

答案 2 :(得分:0)

因为this函数中的draw会引用Engine.prototype.tile对象,而不是您所期望的。

更改

Engine.prototype.tile = {
  draw: function (x, y, tile) {
    this.handle.fillText(tile, x * 16, y * 16);
  };
}

Engine.prototype.tile = function() {
  var self = this;
  return {
    draw: function (x, y, tile) {
      self.handle.fillText(tile, x * 16, y * 16);
    };
  };
}

并称之为:

Engine.prototype.start = function (mapData) {
    this.tile().draw(mapData);
};