2011-01-30 50 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函数?在那种情况下,执行闭包函数即是一种功能。

相关问题