![](/img/trans.png)
[英]Javascript: Calling functions within functions and overwriting variables
[英]JavaScript - saving variables inside functions without calling the functions
有人可以幫助我解決JavaScript難題嗎?
考慮以下JavaScript代碼:
var a[];
for (i=0;i<10;i++)
{
a[i] = function(){alert ("I am " + i);};
}
a[5]();
現在顯然,最后一行將使警報讀取“ I am 9”,而不是“ I am 5”,因為在for
循環結束時i
值為9。
我希望警報打印“它應該做什么”,但不更改我從數組調用函數的方式,即-無參數。
我收到的提示:嘗試定義一個調用另一個函數的函數。
請幫忙!!! 謝謝 :-)
您收到的提示有些欺騙性。 您不想定義一個調用另一個函數(您將遇到同樣的問題)。 相反,您想定義一個返回另一個值的對象。
示例: 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 = [];
這有效:
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);};
}
以下代碼將起作用:
var a[];
for (i=0;i<10;i++)
{
a[i] = (function(i) {
return function(){alert ("I am " + i);};
})(i);
}
a[5]();
在這里, i
被轉換為局部變量。
var a[];
for (i=0;i<10;i++)
{
a[i] = function(){alert ("I am " + i);};
}
a[i = 5]();
作弊自(i = 5)=== 5
千萬不要這樣做
使用上面的實際解決方案之一。
或者:
var a = [];
for (i=0;i<10;i++)
{
(function(j) {
a[j] = function() {
alert ("I am " + j);
};
}(i))
}
a[i]();
使用閉包使j
為i
的當前值
您的第一個示例不起作用的原因是,數據必須存儲在某處 。 您要存儲十個不同的值,但是只有一個i變量,因此它不起作用。
其他張貼者建議使用閉包,這種方法很有效,但是您的問題是尋找一種無需調用函數即可完成閉包的方法。 我建議這樣做:
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且不帶參數的函數? 在這種情況下,閉包功能就可以實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.