JavaScript的Array调用和函数在Prototype中失败

时间:2012-07-03 11:16:56

标签: javascript prototype

我有这段代码:

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')

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

我做错了什么? :(我只是像原型中的任何其他值一样访问数组)。对象内的对象是否有问题?

2 个答案:

答案 0 :(得分: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
    });
}

答案 1 :(得分:0)

  

好像原型中不存在。

不,确实如此。

  

我只是访问数组

这就是你没有的。 this未指向事件侦听器中的Keyboard实例。

当函数被调用为事件监听器时,DOM元素将成为上下文(jQuery也是如此)。请参阅MDN的this keyword概述。您可以使用闭包作用域变量来保存对实际实例的引用,例如描述here(有很多问题)。

可能的快速解决方法:

  • $('body').keydown( (function(){...}).bind(this))
  • var that=this; $('body').keydown(function(){ that.pressedKeys...; });