关于JavaScript闭包与全局变量的疑问:循环中var绑定输出为5的原因
为什么循环中用var时,调用返回i的函数会输出5?
你说的没错,用var声明的i在整个作用域里是单个绑定,所有循环里创建的函数都共享同一个i变量的引用,而非拿到循环当时的i值,这就是问题的核心。
我们一步步拆解代码执行过程:
- 初始化
result数组,var i会被变量提升,此时i为undefined。 - 进入循环:
- 第一次循环:
i赋值为0,满足i<5,给result[0]赋值一个函数——这个函数里的return i并没有立刻求值,只是保存了对i的引用。随后执行i++,i变为1。 - 第二次到第四次循环:重复上述逻辑,每次循环结束
i都会自增,最后一次循环结束后,i变为5,此时i<5不成立,循环终止。
- 第一次循环:
- 当你调用
result[0]()时,函数才会去取i的当前值——这时候循环已经跑完,i的最终值就是5,所以返回结果为5。
并不是调用时i额外自增了,而是循环结束后i本身就停在了5,数组里所有函数只要在循环结束后调用,都会返回这个最终值。
如果想让每个函数返回对应循环迭代时的i值,有两种常用解决办法:
- 改用
let声明i:let在每次循环迭代时都会创建新的绑定,每个函数拿到的是当前迭代的i的独立引用:var result = []; for(let i = 0; i < 5; i++){ result[i] = function(){ return i; } } console.log(result[0]()) // 输出0 - 用立即执行函数(IIFE)创建独立作用域,把当前
i值传入:var result = []; for(var i = 0; i < 5; i++){ result[i] = (function(num){ return function(){ return num; } })(i); } console.log(result[0]()) // 输出0
内容的提问来源于stack exchange,提问作者Roma Kim
相关产品推荐
相关产品推荐

