有人可以用JavaScript谜语帮助我吗?
考虑以下JavaScript代码:
var a[];
for (i=0;i<10;i++)
{
a[i] = function(){alert ("I am " + i);};
}
a[5]();
现在很明显,最后一行将导致警报显示“我是9”,而不是“我是5”,因为i
的值在for
结束时为9循环。
我希望警报打印“它应该是什么”,但不改变我从数组中调用函数的方式,即 - 没有参数。
我收到的提示:尝试定义一个调用另一个函数的函数。
请帮忙!!!谢谢: - )
答案 0 :(得分: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 = [];
答案 1 :(得分: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);};
}
答案 2 :(得分:1)
以下代码可以使用:
var a[];
for (i=0;i<10;i++)
{
a[i] = (function(i) {
return function(){alert ("I am " + i);};
})(i);
}
a[5]();
此处i
转换为本地变量。
答案 3 :(得分:1)
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
答案 4 :(得分:0)
您的第一个示例不起作用的原因是,数据必须存储在某处。您有十个不同的值要存储,但只有一个 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的函数,该API不带参数调用它?在这种情况下,做闭包函数 - 那使得函数成为事物。