You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何call1与call2中timer变量在setTimeout下表现不同?

为什么call1的timer变量会在多次调用间保留,而call2的每次调用都会重新初始化?

我编写了两个使用setTimeout()的相似函数call1和call2,期望实现延迟1000毫秒打印内容的效果。但运行后发现,call1中的timer变量在多次调用间会保留,而call2的timer变量每次调用都会重新初始化,请问这是什么原因?

代码示例

const myFunction= (d) => {
    let timer ;
    return function(){
        if (timer) console.log("funCall1 : timer is still present");else console.log("funCall1 : timer not present")
        timer = setTimeout(()=>{
            console.log("funCall1 : inside setTimeout")
        },d)
    }
}

const call1=myFunction(1000)

function call2(){
  let timer;
  if(timer)
  console.log("funCall2 : timer is present")

  timer = setTimeout(()=>{
    console.log("funCall2 : abc")
  },1000)
}

call1()
call1()
call1()

call2()
call2()
call2()

运行输出

funCall1 : timer not present
funCall1 : timer is still present
funCall1 : timer is still present
funCall1 : inside setTimeout
funCall1 : inside setTimeout
funCall1 : inside setTimeout
funCall2 : abc
funCall2 : abc
funCall2 : abc

原因解析

核心差异来自闭包的特性:

  • 对于call1:它是myFunction执行后返回的内部函数。当myFunction(1000)执行时,会创建局部变量timer,同时返回的内部函数会保留对这个变量所在作用域的引用。之后每次调用call1,都是操作同一个作用域里的timer变量——第一次调用时timer为undefined,所以打印"timer not present",随后被赋值为setTimeout的返回值;第二次、第三次调用时,timer已经有值,因此打印"timer is still present"。
  • 对于call2:timer是call2函数内部的局部变量,每次调用call2时,函数都会重新创建这个变量,初始值为undefined,所以永远不会触发if(timer)的分支逻辑,也就不会打印对应的日志,每次调用都会重新赋值一个新的setTimeout返回值。

内容的提问来源于stack exchange,提问作者reed richards

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:49:53