let和var特性去了解闭包问题的特性

下列代码输出结果为?

for(var i = 0; i < 3; i++){

setTimeout(function(){

console.log(i); },0);

};

输出结果是:3,3,3

为什么不是0,1,2呢?

如果换成

for (var i = 0; i < 3; i++) { (function(i) {

setTimeout(function () {

console.log(i); }, 0, i)

})(i) };

就可以输出012

主要原因是setTimeout是异步函数,所以他会在最后再去获取i,var和let的特性不同,var是函数作用域,而let是块级作用域,使用 var 声明 i 时,i 具有函数作用域,而且它是在全局范围内声明的。

因此,在循环结束后,i 的值变成了 3。而用let去声明变量的时候,每次迭代的时候都会去创建一个新的变量i去存储,所以能够输出012。

使用var去定义,是一个典型的闭包问题,让我解释一下为什么这是闭包:

  1. for 循环中,你使用了 var 声明了变量 i,这将使 i 具有函数作用域。

  2. setTimeout 的回调函数内部,它引用了变量 i。即使 setTimeout 是异步执行的,它仍然可以访问和引用 for 循环中的 i 变量。

  3. setTimeout 的回调函数执行时,它访问的是外部函数作用域中的 i 变量,而不是在函数内部声明的 i

这也侧面反应了闭包问题的特性就是,优点是能够更新新的数据,

但是缺点是,不利于去存储迭代的数据。且内存消耗:由于闭包保留了对外部作用域的引用,它们可能导致内存泄漏问题,特别是当闭包的生命周期比外部函数长时。

 

posted @   Ly021  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示