2015-01-31 3 views
0

Я знакомлюсь с javascript, пообщавшись с ElevatorSaga. Я дошел до того, что мне передали массив с четырьмя лифтовыми объектами. Я бы хотел определить один и тот же прослушиватель событий для всех из них, не дублируя много кода. Я пытался сделать это таким образом, но это не похоже на работу:Можно ли определить прослушиватель событий для каждого объекта в массиве?

{ 
    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

Использовать 'this' внутри прослушивателя событий – adeneo

+2

Также' elevators' является объектом массива, лифтом будет либо индекс массива, либо свойство объекта массива, а не фактический объект лифта. –

ответ

0

Есть две проблемы. Во-первых, elevators является массивом, поэтому цикл for будет перебирать числовые индексы, не значениями массива. Вы на самом деле хотите

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

Другая проблема - это то, что известно как переменный подъем. Ваш для цикла эквивалентно

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.

+3

'elevators' - массив,' лифт' будет номером индекса массива (или даже других свойств объекта массива). Поскольку лифт - это число, функция 'on' отсутствует. –

+0

@PatrickEvans И я попал в ловушку старости! Вот почему я никогда не использую «for .. in» loops. Спасибо, я обновил свой ответ. –

+1

@PatrickEvans: Фактически, поскольку 'for in' loop перечисляет имена свойств,' Elevator' будет (числовой) * строкой *. – Bergi

Смежные вопросы