【前端面試題】閉包問題


一、視頻

閉包視頻講解:蛋老師視頻

二、未閉包

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