2014-11-02 247 views
1

不知何故,当执行此代码时,我从行29 .mouseOnSeat得到警报。 但我不知道为什么this.seats为空,而在绘制函数它不是。 我从html5调用init函数。Javascript undefined error:`this` is null

//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打电话,有人建议在另一篇文章,但我没弄明白。

+0

什么是第29行?你能提供一个jsfiddle吗? – 2014-11-02 20:52:31

+0

你确定'Cinema'的两个定义没有冲突吗? – fejese 2014-11-02 21:10:01

+0

http://jsfiddle.net/2eu7841h/,它现在在第32行 – 1elf 2014-11-02 21:24:34

回答

1

的问题是,当你调用addEventListener,变量this不随身携带的函数调用。这意味着this不是你的对象。

你的解决方法是健全的,你可以使用它。或者alteratively改变你addEventListener呼吁:

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

请注意,您可能需要使用填充工具来获得Function.prototype.bind对旧版浏览器,但它是很好的当前支持。见caniuse

+0

谢谢,这个工程。 Javascript仍然是我的克星。 – 1elf 2014-11-02 21:35:48

0

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

但我不知道为什么

+0

请编辑格式 – Artemis 2014-11-02 21:28:39