【问题标题】:IIFE and Arrow Functions with setInterval plain JS带有 setInterval 纯 JS 的 IIFE 和箭头函数
【发布时间】:2026-02-17 19:55:02
【问题描述】:

我有以下代码:

window.setInterval((array => {
  console.log(array[0]++);
  console.log(array[1]++);
})([0, 0]), 500);

我希望上面的代码每次运行(500 毫秒)都会产生 00。然而,事实并非如此。它只跑了一次。当我尝试时:

window.setInterval((array => () => {
  console.log(array[0]++);
  console.log(array[1]++);
})([0, 0]), 500);

成功了。我认为第一个仍然会每 500 毫秒打印一次 00,因为带有参数 array 的 IIFE 每次运行总是会被赋予值 [0, 0](但是,情况并非如此,它运行只有一次!)。然后,第二个代码以某种方式允许array“记住”其先前的值并在每次运行时更新其值。有人可以向我解释一下吗?

【问题讨论】:

    标签: javascript arrow-functions iife


    【解决方案1】:

    传递给setInterval 的第一个参数应该是一个函数。在第一个 sn-p 中,您立即调用一个函数并返回undefined

    window.setInterval((array => {
      console.log(array[0]++);
      console.log(array[1]++);
    })([0, 0]), 500);
    

    等价于

    window.setInterval(() => {
      // do something, return undefined
    })(), 500);
    

    一旦 IIFE 被评估:

    window.setInterval(undefined, 500);
    

    所以,您需要像第二个 sn-p 这样的东西,其中 IIFE 还返回一个函数:

    window.setInterval((array => () => {
      console.log(array[0]++);
      console.log(array[1]++);
    })([0, 0]), 500);

    不过,您可以考虑在外部 IIFE 中定义 array 以使代码更清晰:

    window.setInterval(
      (() => {
        const array = [0, 0];
        return () => {
          console.log(array[0]++);
          console.log(array[1]++);
        };
      })(),
      500
    );

    【讨论】:

    • 啊,我明白了!对,我需要在setInterval 中传递一个函数表达式,而不是执行我的函数。所以在我的第二个 sn-p 中,我传递了一个 IIFE 表达式,稍后每 500 毫秒调用一次,对吧?
    • 是的,第一个sn-p的函数被立即调用,不再,而第二个sn-p的函数在500ms、1000ms等之后被调用
    • 更多问题。所以我在这里使用 IIFE 为我的数组提供一个词法范围,它不会污染全局范围,同时防止从“外部”访问我的 array 变量,对吧?
    • 是的 - 我只是认为如果这是目标,在外部 IIFE 内部定义它会更清晰,而不是用它调用外部 IIFE。
    • 谢谢。我现在知道了。我同意你的更容易理解。