var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
它输出:
My value: 3
My value: 3
My value: 3
而我希望它输出:
My value: 0
My value: 1
My value: 2
当由于使用事件侦听器而导致功能运行延迟时,会发生相同的问题:
var buttons = document.getElementsByTagName("button");
// let's create 3 functions
for (var i = 0; i < buttons.length; i++) {
// as event listeners
buttons[i].addEventListener("click", function() {
// each should log its value.
console.log("My value: " + i);
});
}
<button>0</button>
<br />
<button>1</button>
<br />
<button>2</button>
…或异步代码,例如使用Promises:
// Some async wait function
const wait = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms));
for (var i = 0; i < 3; i++) {
// Log `i` as soon as each promise resolves.
wait(i * 100).then(() => console.log(i));
}
这个基本问题有什么解决方案?
嗯,问题在于i
每个匿名函数中的变量都绑定到函数外部的相同变量。
您要做的是将每个函数中的变量绑定到函数外部的一个不变的值:
var funcs = [];
function createfunc(i) {
return function() {
console.log("My value: " + i);
};
}
for (var i = 0; i < 3; i++) {
funcs[i] = createfunc(i);
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
由于JavaScript中没有块作用域-只有函数作用域-通过将函数创建包装在新函数中,因此请确保“ i”的值保持预期。
随着该Array.prototype.forEach
功能的使用相对广泛(在2015年),值得注意的是,在那些主要涉及对值数组进行迭代的情况下,.forEach()
该方法提供了一种干净自然的方法来为每次迭代获取不同的闭包。也就是说,假设您有某种包含值的数组(DOM引用,对象等),并且出现了针对每个元素设置回调的问题,则可以执行以下操作:
var someArray = [ /* whatever */ ];
// ...
someArray.forEach(function(arrayElement) {
// ... code code code for this one element
someAsynchronousFunction(arrayElement, function() {
arrayElement.doSomething();
});
});
这个想法是,与.forEach
循环一起使用的回调函数的每次调用都将是其自己的闭包。传递给该处理程序的参数是特定于迭代的特定步骤的数组元素。如果在异步回调中使用它,它将不会与在迭代其他步骤中建立的任何其他回调发生冲突。
如果您碰巧在jQuery中工作,该$.each()
函数将为您提供类似的功能。
let
ECMAScript
6(ES6)引入了新的let
和const
关键字,其作用域与var
基于变量的作用域不同。例如,在let
基于索引的循环中,循环中的每次迭代都会有一个i
具有循环范围的新变量,因此您的代码将按预期工作。有很多资源,但是我建议2ality的块定义范围文章作为大量信息来源。
for (let i = 0; i < 3; i++) {
funcs[i] = function() {
console.log("My value: " + i);
};
}
但是请注意,IE9-IE11和Edge
14之前的Edge支持,let
但是出现了上述错误(它们不会i
每次都创建一个新的,因此上面的所有功能都将记录3,就像我们使用一样var
)。Edge
14终于正确了。
问题内容: 目前,我正在为Java测试学习。在学习期间,我遇到了一个小问题。 在此for循环中: 输出为: 我的问题是,我不了解。当我阅读这段代码时,我一直认为它应该看起来像这样: 为什么不是这样? 问题答案: i的每次迭代都将开始j的全新迭代。 因此,从i == 1开始,然后在循环中j == 1,2,3。然后i == 2,然后j == 1,2,3循环,依此类推。 一次一步地执行它,这将是有意义的
本文向大家介绍javascript实现的闭包简单实例,包括了javascript实现的闭包简单实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了javascript实现的闭包。分享给大家供大家参考。具体如下: 希望本文所述对大家的javascript程序设计有所帮助。
本文向大家介绍jQuery的each循环用法简单示例,包括了jQuery的each循环用法简单示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了jQuery的each循环用法。分享给大家供大家参考,具体如下: 更多关于jQuery相关内容感兴趣的读者可查看本站专题:《jquery中Ajax用法总结》、《jQuery表格(table)操作技巧汇总》、《jQuery拖拽特效与技巧总结》、《j
我只收到一个测试用例的错误。 问题链接:https://www.hackerrank.com/challenges/java-loops/problem?isFullScreen=trueJAVA黑客等级循环问题 我得到了精确的输出,但是测试用例失败了。 Java代码:
问题内容: 希望我能得到最简单的示例代码,该示例代码将演示如何使用LMAX干扰器(http://code.google.com/p/disruptor/)。 不幸的是,每段代码都是过时的。有人知道吗,在哪里可以找到最新的小型方法(最好不使用DSL)? 问题答案: 您可以在此处查看示例。 http://code.google.com/p/disruptor/wiki/CodeExampleDisru
我刚开始学习Haskell,但是现在没有循环是非常令人沮丧的。我想出了如何为函数编写循环。然而,我的问题是,我想在迭代循环时输出一些结果。似乎我必须使用debug来执行这个简单的任务。 所以现在我只想举一个例子,说明如何在主结构中打印字符串10次。 换句话说,我想这样做10次: 谢谢。我觉得这对我的任务很有启发。