2015-01-31 83 views
0

我正在通過與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

在事件監聽器內使用'this' – adeneo 2015-01-31 19:22:45

+2

另外'elevators'是一個數組對象,lift將是數組索引或數組對象的屬性,而不是實際的電梯對象。 – 2015-01-31 19:35:18

回答

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

+3

「電梯」是一個數組,「電梯」將成爲數組的索引(甚至是數組對象的其他屬性)。由於電梯是一個號碼,所以沒有「開」功能。 – 2015-01-31 19:33:46

+0

@PatrickEvans我已經陷入了一個老年陷阱!這就是爲什麼我從不使用'for .. in'循環。謝謝,我已經更新了我的答案。 – 2015-01-31 19:41:28

+1

@PatrickEvans:事實上,作爲'for in'循環枚舉屬性名稱,'elevator'將是一個(數字)*字符串*。 – Bergi 2015-01-31 20:01:17

相關問題