js关于静态快照(snapshot)的问题

在JavaScript中,由于静态快照的原因,当在循环中创建函数并延迟执行时,所有函数内部引用的变量将是循环结束时的值。本文通过一个例子展示了这个问题,并提出使用闭包作为解决方案,确保每个函数都能正确捕获到循环中的当前值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有这么一个情景,JS代码 如下:

  1. var map = ['Mr' : 'Mr' , 'Ms' : 'Ms'];//可能有很多个
  2. var hello = [];
  3. function say(call , name){
  4.     console.log(call + " : " +  name );
  5. //补全代码
  6. bababa~~~~
  7. //补全代码
  8. hello.Mr('JuMorZhu') // 控制台输出 Mr : JuMorZhu
  9. hello.Ms('Fan BingBing') // 控制台 Ms : Fan BingBing
  10. 一开始我想到的是这样:

for( var x  in map){

  hello[x] = function(name){

               say(map[x],name)

   }

}

感觉挺简单的,自己还在得意中的时候控制台给我来了一波冷水。。。(+﹏+)~,输出的都是Ms : Fan BingBing,我擦,你是有多喜欢范冰冰!!!

原因是这样的,有没有听过这么一个名词: 静态快照,是这样的,当你在执行这段代码的时候,Js首先进入预编译阶段,因为你创建函数的时候没有立即执行,所以JS在预编译的时候就会引用这个变量而不是这个变量的值,当你的函数执行的时候才会去找这个变量,在它找这个变量的时候他找不到,就会返回上一层作用域去找这个变量,而这时这个变量是map[x],而x现在是map数组的最后一个索引,也就是Ms,所以此时无论你hello中有多少个元素,都只有一种输出结果,也就是在这种情况下创建的函数不支持静态快照。

所以你需要换个思路了~

如果说函数执行的时候才去找变量,那么我们问什么不把它运行下呢,这时候我们用到了闭包。

再来看看用闭包写的代码:

for(var x in map){

  hello[x] = (function( call ){

    say(call,name)

})( map[x] )

}

你再试试,怎么样?感受到闭包的强大了吧~

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值