首页 > 解决方案 > 为什么 JavaScript 闭包会这样工作?这段代码是否应该像这样工作

问题描述

我确实理解 javascript 闭包,我用它做了很多小程序,但在这段代码中,我不明白的是,当我调用数组中的函数时,为什么它们打印出不同的“i”值他们不应该指的是同一个“我”吗?

function makeFunctionArray() {
      const arr = []
    
      //let i = 0
      for (let i = 0; i < 5; i++) {
        arr.push(function () { console.log(i) })
      }
      
      //console.log(i)
    
      return arr
    }
    
    let functionarr = makeFunctionArray() 
    functionarr[0]() //print out 0
    functionarr[2]() //print out 2
    functionarr[1]() //print out 1

标签: javascriptclosures

解决方案


  • 当你这样做

      for (let i = 0; i < 5; i++) {
          arr.push(function () { console.log(i) })
      }
    

会有arr

[console.log(0),
 console.log(1),
 console.log(2),
 console.log(3),
 console.log(4)];

所以当你回来arr然后你functionarr像这样打电话

functionarr[0]() //print out 0
functionarr[2]() //print out 2
functionarr[1]() //print out 1

它会返回:

console.log(0);
console.log(1);
console.log(2);

记住:这是一个范围问题。如果使用var,当您将i变量调用到数组函数中时,它将返回最后一个i值。这就是为什么它总是返回 5 的原因。如果你使用let,它会返回本地i值,所以它会保存[0, 1, 2, 3, 4]

  • 使用let

const arr = [];

for (let i = 0; i < 5; i++) {
    arr.push(
      function () { 
        console.log(i);   //i value at the moment that you create function would be saved 
      }
    );  
}

arr[0]();  //print 0

  • 使用var

const arr = [];

for (var i = 0; i < 5; i++) {
    arr.push(
      function () { 
        console.log(i);   //final i value would be saved (current i value)
      }
    );  
}

arr[0]();  //print 5


推荐阅读