gpt4 book ai didi

javascript - 在这里创建闭包的替代方案是什么?

转载 作者:行者123 更新时间:2023-12-02 16:25:56 26 4
gpt4 key购买 nike

假设我们有一个简单对象列表:

var things = [
{ id: 1, name: 'one' },
{ id: 2, name: 'two' },
{ id: 3, name: 'three' }
];

我们需要迭代这些对象并将它们注册为后续事件的参数。天真的方法在所有回调之间共享相同的对象引用,因此每个回调都会针对最后项触发:

for (var i = 0; i < things.length; i++) {
var o = things[i];
setTimeout(function() { doSomethingWith(o); }, i * 1000);
}

典型的解决方案是创建一个闭包,限制对象引用的范围:

for (var i = 0; i < things.length; i++) {
(function() {
var o = things[i];
setTimeout(function() { doSomethingWith(o); }, i * 1000);
})();
}

如果我们不针对 IE<9,我们可以依赖 .forEach():

things.forEach(function(o, i) {
var o = things[i];
setTimeout(function() { doSomethingWith(o); }, i * 1000);
});

但是,在这种情况下,我们最终通过将匿名函数传递给 forEach() 来创建了一种闭包。

有没有办法在没有闭包或函数引用的情况下完成此任务?

根本问题有三个:

  1. 不太重要的是:传递给 setTimeout() 的函数引用(或任何可能的内容)让你(我)感觉像你一样正在创建一个关闭。所以,我有忘记外部封闭的倾向。
  2. 更重要的是:额外的函数/闭包声明鼓励“箭头代码”。对于复杂的操作,随着代码移出屏幕,复杂操作的代码可读性很快就会恶化...这可能可以通过 IE>9 中的 .forEach() 解决,除非应用程序或组织风格指南规定换行符 + 缩进作为结束符。
  3. 重要的是:我非常确定有一种简单的方法可以处理这个问题。我因为现在无法想到这一点而感到愚蠢。

也许更好的提问方式是:在我们开始强制性地创建闭包之前我们都做了什么?

最佳答案

我不认为在这里使用闭包有什么问题。它们是 javascript 中的自然工具,对于具有本地状态的异步回调来说是相当必要的 - 因为我们希望避免全局状态。

如果您非常关心缩进,则可以将提供范围的 IEFE 与循环放在同一行:

for (var i = 0; i < things.length; i++) (function() {
var o = things[i];
setTimeout(function() { doSomethingWith(o); }, i * 1000);
}());

否则,您已经完美地使用了forEach。请注意,您不需要在代码中关心 IE<=8,因为如果您想支持 forEach ,它是很容易调整的。

当然,ES6 将为我们提供 let 语句来解决这个问题 very common problem使用新语法 - 不过您需要使用 6to5 转换器:

for (let i = 0; i < things.length; i++) {
// ^^^
var o = things[i];
setTimeout(function() { doSomethingWith(o); }, i * 1000);
}

如果你想要一个非常清晰的代码组织,请明确闭包:

function makeDoer(thing) {
return function() { doSomethingWith(thing); };
}
for (var i = 0; i < things.length; i++) {
setTimeout(makeDoer(things[i]), i*1000);
}

What the devil did we all do before we all started compulsively creating closures?

我们使用全局状态,并以不同的方式解决我们的问题。例如,您的情况可以通过半递归函数更好地解决:

var i = 0;
function next() {
if (i < things.length) {
doSomethingWith(things[i++]);
setTimeout(next, 1000);
}
}
next();

关于javascript - 在这里创建闭包的替代方案是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28701290/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com