是否可以为数组中的每个对象定义一个事件侦听器?

时间:2015-01-31 19:14:21

标签: javascript

我通过弄乱ElevatorSaga来熟悉javascript。我已经到了我用四个电梯对象递送阵列的地步。我想为所有这些事件定义相同的事件监听器,而不需要复制大量代码。我尝试这样做,但它似乎没有效果:

{
    init: function(elevators, floors) {
        for(var elevator in elevators)
        {
            elevator.on("idle", function() {
                elevator.goToFloor(3);
            })
        }      
    },
    update: function(dt, elevators, floors) {
        // We normally don't need to do anything here
    }
}

有没有办法做我想在这里做的事情?

1 个答案:

答案 0 :(得分:0)

有两个问题。第一个是elevators是一个数组,所以你的for循环将遍历数字索引,数组的值。你真的想要

for( var i = 0; i < elevators.length; i++ ) {
    elevators[i].on( … );
}

另一个问题是所谓的可变吊装。你的for循环相当于

var elevator;
for( elevator in elevators ) {
    // …
}

事实上,这正是Javascript引擎所能做到的。 elevator的值在执行函数时会发生变化 - 它将保留elevators的最后一个元素。

这里可以看到同样的问题:

for( var i = 1; i <= 5; i++ ) {
    setTimeout( function () {
        alert( i );
    }, 1000 );
}

您希望它提醒1,然后提醒2等等5,对吧?错误!运行它,你会看到它只是警告6多次(确切地说是五次)。

解决这两个问题的一种方法是使用this

for( var i = 0; i < elevators.length; i++ ) {
    elevators[i].on( "idle", function () {
        this.goToFloor( 3 );
    } );
}

还有其他方法可以解决这个问题,例如在循环中引入临时变量(丑陋!)或使用bind(跨浏览器问题)。最简单的解决方案是使用this