0

我有这个代码:

function Keyboard() {

    this.log = $('#log')[0];
    this.pressedKeys = [];

    this.bindUpKeys = function() {
        $('body').keydown(function(evt) {
            this.pressedKeys.push(evt.keyCode);

            var li = this.pressedKeys[evt.keyCode];

            if (!li) {
                li = this.log.appendChild(document.createElement('li'));
                this.pressedKeys[evt.keyCode] = li;
            }

            $(li).text('Down: ' + evt.keyCode);
            $(li).removeClass('key-up');
        });
    }

    this.bindDownKeys = function() {
        $('body').keyup(function(evt) {
            this.pressedKeys.push(evt.keyCode);

            var li = this.pressedKeys[evt.keyCode];

            if (!li) {
                li = this.log.appendChild(document.createElement('li'));
            }

            $(li).text('Up: ' + evt.keyCode);
            $(li).addClass('key-up');
        });
    }

}

我收到这些错误:

TypeError: 'undefined' is not an object (evaluating 'this.pressedKeys.push')

我想对数组做什么并不重要,它只是不断给我访问错误,就好像它在原型中不存在一样。

我究竟做错了什么?:( 我只是将数组作为原型中的任何其他值访问)。对象内部的对象有问题吗?

4

2 回答 2

2

问题是事件处理程序内部this不是你想的那样。您可以将事件处理函数与bind方法绑定(或者,因为它看起来像您正在使用 jQuery,$.proxy):

this.bindUpKeys = function() {
    var that = this;
    $('body').keydown($.proxy(function(evt) {
        //Use `this` as normal inside here
    }, this));
}

this或者您可以存储对事件处理程序外部的引用,例如

this.bindUpKeys = function() {
    var that = this;
    $('body').keydown(function(evt) {
        //Use `that` instead of `this` in here
    });
}
于 2012-07-03T11:19:53.093 回答
0

就好像它在原型中不存在一样。

不,确实如此。

我只是访问数组

那是你不知道的。this不指向您Keyboard在事件侦听器中的实例。

当函数作为事件侦听器调用时,DOM 元素将成为上下文(jQuery 也这样做)。请参阅 MDN 的this关键字概述。您可以使用闭包范围的变量来保存对实际实例的引用,例如此处描述的示例(对此有很多问题)。

可能的快速修复:

  • $('body').keydown( (function(){...}).bind(this))
  • var that=this; $('body').keydown(function(){ that.pressedKeys...; });
于 2012-07-03T11:20:31.313 回答