【前端面试题】闭包问题


一、视频

闭包视频讲解:蛋老师视频

二、未闭包

for (var i = 0; i < 5; i++) {
    setTimeout(() => {
      console.log(i++);
    }, 4000)
  }
  console.log(i);//5
//输出结果为:5,5,6,7,8,9

在这里插入图片描述

{
    var i = 0
    setTimeout(() => {
      console.log(i++);
    }, 4000)
  }
  {
    var i = 1
    //放入任务队列,等待同步任务执行后,再根据延迟时间执行
    setTimeout(() => {
      console.log(i++);
    }, 4000)
  }
  {
    var i = 2
    //放入任务队列,等待同步任务执行后,再根据延迟时间执行
    setTimeout(() => {
      console.log(i++);
    }, 4000)
  }
  {
    var i = 3
    //放入任务队列,等待同步任务执行后,再根据延迟时间执行
    setTimeout(() => {
      console.log(i++);
    }, 4000)
  }
  {
    var i = 4
    //放入任务队列,等待同步任务执行后,再根据延迟时间执行
    setTimeout(() => {
      console.log(i++);
    }, 4000)
  }
  {
    var i = 5
    // i<5不成立,不继续执行
  }

  // 执行全局console.log(i),输出i等于5
  // 4000ms延迟时间到,此时var=5(var没有块级作用域,除了function函数),所以输出5次 console.log(i++)
  // 输出5,6,7,8,9

注:
1.setTimeout是异步,先放到任务队列,同步执行完后,任务队列里面再根据时间执行;
2.var没有块级作用域,所以for循环之后,i的值变为5,所以全局先输出5
3.匿名函数可以访问到外部i的值

在这里插入图片描述

三、采用闭包

for (var i = 0; i < 5; i++) {
    (function (x) {
      setTimeout(function () {
        console.log(x++);
      }, 400)
    })(i)
  }
  console.log(i);//5
  输出结果:5   0,1,2,3,4

在这里插入图片描述

{
    var i = 0
      //i=0放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
      (function (x) {
        setTimeout(function () {
          console.log(x++);
        }, 400)
      })(i)
  }
  {
    var i = 1
      //i=1放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
      (function (x) {
        setTimeout(function () {
          console.log(x++);
        }, 400)
      })(i)
  }
  {
    var i = 2
      //i=2放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
      (function (x) {
        setTimeout(function () {
          console.log(x++);
        }, 400)
      })(i)
  }
  {
    var i = 3
      //i=3放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
      (function (x) {
        setTimeout(function () {
          console.log(x++);
        }, 400)
      })(i)
  }
  {
    var i = 4
      //i=4放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
      (function (x) {
        setTimeout(function () {
          console.log(x++);
        }, 400)
      })(i)
  }
  {
    var i = 5
    // i<5不成立,不继续执行
  }

  // 执行全局console.log(i),输出i等于5,因为此时var=5,并且var不支持块级作用域
  //调用任务队列里面的 
  /*(function (x) {
        setTimeout(function () {
          console.log(x++);
        }, 400)
      })(i)*/
  // 依次输出0,1,2,3,4


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM