闭包

请注意,本文编写于 192 天前,最后修改于 190 天前,其中某些信息可能已经过时。

闭包的定义很简单:函数A返回了一个函数B,并且函数B中使用了函数A的变量,函数B就被称为闭包.

function A(){
    let a = 1;
    function B(){
        console.log(a);
    };
return B;
};

你是否会疑惑,为什么函数A已经弹出调用栈了,为什么函数B还能引用到函数A中的变量.因为函数A中的变量这时候是存储在堆上的.现在的JS引擎可以通过逃逸分析辨别出那些变量需要存储在堆上,那些需要存储在栈上.

经典面试题,循环中使用闭包解决var定义函数的问题.

for(var i = 1;i <= 5;i++){
    setTimeout(function timer(){
       console.log(i);
},i*1000);
}

首先因为setTimeout是个异步函数,所以会先把循环全部执行完毕,这时候i就是6了,所以会输出一堆6.

解决方法两种,第一种使用闭包.

for(var i = 1;i <= 5;i++){
    (function(j){
     setTimeout(function timer(){
     console.log(j);
     },j*1000);
})(i);
}

第二种就是使用setTimeout的第三个参数

for(var i = 1;i <= 5;i++){
  setTimeout(function timer(j){
   console.log(j);
},i*1000,i);
}

第三种就是使用let定义i了.

for(let i = 1;i <=5;i++){
   setTimeout(function(){
    console.log(i);
},i*1000);
}

因为对于let来说,他会创建一个块级作用域,相当于

{ // 形成块级作用域
  let i = 0
  {
    let ii = i
    setTimeout( function timer() {
        console.log( ii );
    }, i*1000 );
  }
  i++
  {
    let ii = i
  }
  i++
  {
    let ii = i
  }
  ...
}
Comments

添加新评论

已有 2 条评论

你貌似加错位置了,你按照我给你的截图加