Javascript未定义错误:`this`为null

时间:2014-11-02 20:47:25

标签: javascript undefined

以某种方式执行此代码时,我从第29行 .mouseOnSeat获取警报。 但我不知道为什么 this.seats 为空,而在 draw 函数中则不是。 我从html5调用init函数。

//init called by html5
function init() {
  var cinema = new Cinema(8, 10);
  cinema.draw("simpleCanvas");

  var canvas = document.getElementById("simpleCanvas");
  //add event listener and call mouseOnSeat
  canvas.addEventListener('mousedown', cinema.mouseOnSeat, false);
}

var Cinema = (function () {
  function Cinema(rows, seatsPerRow) {
    this.seats = [];
    this.rows = rows;
    this.seatsPerRow = seatsPerRow;

    var seatSize = 20;
    var seatSpacing = 3;
    var rowSpacing = 5;

    var i;
    var j;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < seatsPerRow; j++) {
            this.seats[(i * seatsPerRow) + j] = new Seat(i, j, new Rect(j * (seatSize +   seatSpacing), i * (seatSize + rowSpacing), seatSize, seatSize));
        }
    }
  }

  Cinema.prototype.mouseOnSeat = function (event) {
    //somehow this is null
    if (this.seats == null) {
        alert("seats was null");
        return;
    }
    for (var i = 0; i < this.seats.length; i++) {
        var s = this.seats[i];
        if (s.mouseOnSeat(event)) {
            alert("Mouse on a seat");
        }
    }
    alert("Mouse not on any seat");
  };

  Cinema.prototype.draw = function (canvasId) {
    var canvas = document.getElementById(canvasId);
    var context = canvas.getContext('2d');
    var i;
    //somehow this isn't
    for (i = 0; i < this.seats.length; i++) {
        var s = this.seats[i];
        context.beginPath();
        var rect = context.rect(s.rect.x, s.rect.y, s.rect.width, s.rect.height);
        context.fillStyle = 'green';
        context.fill();
    }
  };
  return Cinema;
})();

我尝试了很多,比如创建一个自变量(var self = this),然后从self.mouseOnSeat调用,这是在另一篇文章中提出的,但我没有弄明白。

2 个答案:

答案 0 :(得分:1)

问题在于,当您致电addEventListener时,变量this不会继续执行函数调用。这意味着this不是您的对象。

你的解决方法是合理的,你可以使用它。或者以替代方式将addEventListener来电更改为:

canvas.addEventListener('mousedown', cinema.mouseOnSeat.bind(this), false);

请注意,可能需要使用polyfill来获取旧版浏览器的Function.prototype.bind,尽管目前支持得非常好。请参阅caniuse

答案 1 :(得分:0)

我找到了一个解决方法: canvas.addEventListener('mousedown', function (event) { cinema.mouseOnSeat(event); }, false);

但我不知道为什么