js 经典闭包题目详解

function test () {
  var arr = []
  for (var i=0; i<10; i++) {
    arr[i] = function () {
      console.log(i)
    }
  }
  return arr
}
var myArr = test()
for (var j =0; j < 10; j ++) {
  myArr[j]()  // 10个10
}

要彻底理解这段代码 必须里面所有内容执行顺序都要清楚

我们看for循环的执行步骤

test函数执行之后给我们返回一个数组

var myArr = [
  function () {console.log(i)},
  function () {console.log(i)},
  function () {console.log(i)},
  function () {console.log(i)},
  function () {console.log(i)},
  function () {console.log(i)},
  function () {console.log(i)},
  function () {console.log(i)},
  function () {console.log(i)},
  function () {console.log(i)},
]

我们循环调用10个函数

for (var j =0; j < 10; j ++) {
  myArr[j]()
}

 每个函数都执行了console.log(i)

我们要去函数所在的上下文,也就是这个函数所在的位置寻找这个i;

每个函数中没有i 就去函数的外层寻找;

通过10次循环自增,此时的i也就是10

所以打印10个10

这个闭包问题的关键:

  1.函数不是立即执行的,所以无法立刻拿到 i 的值,也就无法正确的显示 i 

     2. 理解for循环,正确的拿到 i 的值

如何解决这个闭包问题,拿到我们想要的值

  函数虽然不是立即执行的,但是我们可以让这个函数能够正确的读取到 i 的值

function test () {
  var arr = []
  for (var i=0; i<10; i++) {
    (function (j) {
      arr[j] = function () {
        console.log(j)
      }
    } (i))
    
  }
  return arr
}
var myArr = test()
for (var j =0; j < 10; j ++) {
  myArr[j]()
}

  通过理解立即执行函数  将j存在立即执行函数中,也就是函数 function(){console.log(j)} 的外层

  当我们访问这个函数function(){console.log(j)} 的时候 就能通过函数的作用域得到j的值

  

                

原文地址:https://www.cnblogs.com/guozongzhang/p/11046203.html