2014-02-20 63 views
1

我有一個循環,用不同的參數使用不同的超時間隔三次調用一個函數:超時會覆蓋數據(JS)

<script type="text/javascript"> 
    var myArray = []; 

    for (i=0; i<3; i++) { 
     myArray[i] = []; 
     myArray[i]['second'] = (1+i)*3000; 
     myArray[i]['valeur'] = i+i; 

     setTimeout(function() { 
      otherfunction(myArray[i]['valeur']); 
     }, myArray[i]['second']); 
    } 

    function otherfunction(data1) { 
     console.log(data1); 
    } 
</script> 

腳本正確調用otherfunction(),但有一個錯誤:

Uncaught TypeError: Cannot read property 'valeur' of undefined

我該如何解決這個問題。看起來像一個關於可變範圍的問題。

+0

的JS陣列並不意味着與鍵一起使用。你想要的是一個JSON對象:'myArray [i] = {}'。 – Stilltorik

+0

在這一點上,變量可能是錯誤的... –

+0

你得到了一個閉環循環問題。所有迭代都指向相同的值。檢查http://stackoverflow.com/questions/8567118/javascript-settimeout-issue-w-for-loop?rq=1 –

回答

4

改變它想:

for (i=0; i<3; i++) 
{ 

    myArray[i] = new Array(); 
    myArray[i]['second'] = (1+i)*3000; 
    myArray[i]['valeur'] = i+i; 


    var timeoutCallback = (function(valeur){ 
     return function(){ 
      otherfunction(valeur); 
     } 
    })(myArray[i]['valeur']); 

    setTimeout(timeoutCallback, myArray[i]['second']); 


} 

的此點使用JavaScript closures保持變量的當前值的範圍內,爲你喜歡的回調函數。

正如你所看到的,我們在這裏有兩個嵌套函數,第一個創建一個安全範圍,以保持當前值myArray[i]['valeur'],這完全取決於變量i,它在for循環中沒有固定值。

有關檢查這個問題更多的信息,這個擁有最有價值的答案永遠

How do JavaScript closures work?

+0

非常感謝你。 – Charlie

0

這是因爲在超時功能

i 

變量已經是3,和你的數組長度是3,所以myArray [3]是未定義的。您需要確保傳遞給setTimeout的函數具有正確值的閉包。

這將工作:

var myArray = new Array(); 

for (i=0; i<3; i++) 
{ 

    myArray[i] = new Array(); 
    myArray[i]['second'] = (1+i)*3000; 
    myArray[i]['valeur'] = i+i; 



    (function(val){ 
     setTimeout(function() 
     { 
      otherfunction(val); 
     },myArray[i]['second']); 
    })(myArray[i]['valeur']); 
} 


function otherfunction(data1) 
{ 
    console.log(data1); 
} 
+0

您的代碼記錄'4'三次。嘗試改變它,所以它記錄'0,2,4'。 – Tibos

+0

你說得對,對不起我的錯誤。我編輯它,當前版本按預期工作。 – kamilkp