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

发布时间 2023-09-25 22:51:36作者: Ly021

下列代码输出结果为?

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

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

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