2011-01-30 83 views
1

有人可以幫我解決一個JavaScript謎題嗎?JavaScript - 在不調用函數的情況下在函數中保存變量

考慮下面的JavaScript代碼:

var a[]; 

for (i=0;i<10;i++) 
{ 
    a[i] = function(){alert ("I am " + i);}; 
} 

a[5](); 

現在很明顯,最後一行將導致警報讀「我是9」,而不是「我5」,因爲i值9在for循環的末尾。

我想要警報打印「它應該是什麼」,但不改變我從數組中調用函數的方式,即 - 沒有參數。

收到的提示:嘗試定義調用另一個函數的函數。

請幫忙!!!謝謝:-)

回答

6

您收到的提示有點欺騙性。你不想定義一個調用另一個的函數(你會遇到同樣的問題)。相反,你想定義一個返回另一個。

實施例:http://jsfiddle.net/sX92Q/

var a = []; 

for (i = 0; i < 10; i++) { 
    a[i] = alertFunc(i); 
} 

    // return a function that closes around the proper value of "i" 
function alertFunc(i){ 
    return function() { 
     alert(i); 
    }; 
}; 

a[5](); 

這是有效的那些相同的是,在循環使用匿名功能,但它是更有效的,因爲匿名函數並不需要重建每次迭代。

通常,您不希望在循環中創建重複函數。


附註。在JavaScript中,這樣的:

var a[]; 

應該是:

var a = []; 
4

這工作:

var a = []; 

for (i=0;i<10;i++) 
{ 
    a[i] = (function(i) { 
     return function(){alert ("I am " + i);}; 
    })(i); 
} 

a[5](); 

在你的榜樣,匿名函數持有參考i變量,但是這個變量函數的創建後修改。所以在你調用函數的時候,你會看到修改後的值。

爲了避免這種情況,您必須複製該變量,這是上述代碼的作用。

另外,在Javascript 1.7你可以使用let定義:

for (i=0;i<10;i++) 
{ 
    let j = i; 
    a[i] = function(){alert ("I am " + j);}; 
} 
+0

非常感謝你! – 2011-01-30 16:36:46

1

下面的代碼將工作:

var a[]; 

for (i=0;i<10;i++) 
{ 
    a[i] = (function(i) { 
     return function(){alert ("I am " + i);}; 
    })(i); 
} 

a[5](); 

這裏i轉換爲一個局部變量。

+1

-1 @levu您有義務需要返回該函數。你剛纔定義了一個[i]在這裏沒有定義。 – Raynos 2011-01-30 16:19:31

+0

@raynos:對不對:) – levu 2011-01-30 17:19:07

1
var a[]; 

for (i=0;i<10;i++) 
{ 
    a[i] = function(){alert ("I am " + i);}; 
} 

a[i = 5](); 

作弊,因爲(i = 5)=== 5

不要actaully做到這一點

使用上述實際解決方案之一。

或者:

var a = []; 

for (i=0;i<10;i++) 
{ 
    (function(j) { 
     a[j] = function() { 
      alert ("I am " + j); 
     }; 
    }(i)) 
} 

a[i](); 

使用閉合,使ji

+0

非常不好的解決方案... – levu 2011-01-30 16:03:28

+0

@levu,但它是一個有趣的想法以外的解決方案!如果這是一個面試問題,我更願意回答。 – Raynos 2011-01-30 16:04:02

0

你的第一個例子不工作的原因是,該數據具有電流值在某個地方存儲。你有10個不同的值來存儲,但只有一個變量,所以它不起作用。

其他海報建議使用封閉,它的工作原理,但你的問題是尋找一種方法來做到這一點沒有調用函數。我建議這樣的:

var a = []; 
for (i=0; i<10; i++) { 
    a[i] = function(i){alert("I am " + i);}; 
} 
a[5](5); 

當然,這讓人懷疑,爲什麼連有十個不同的功能時,他們都做同樣的事情?爲什麼不乾脆:

var whoAmI = function(i){ alert("I am " + i); }; 
whoAmI(5); 

也許你需要,你可以通過周圍,其不帶參數調用它的一些外部API函數?在那種情況下,執行閉包函數即是一種功能。

相關問題