JS使用var声明for循环i时的变量提升与闭包特性疑问
var在for循环中的变量绑定与闭包问题解答
问题1:循环结束i为4为何不报错、是否和声明的i绑定
- 首先要明确for循环的执行顺序:先做条件判断,条件成立才会执行循环体代码,完整执行顺序为:
- 初始化
var i = 0 - 判断
i < arr.length是否成立 - 成立则执行循环体的
console.log(arr[i]),不成立直接终止循环 - 执行
i++,回到步骤2重复
- 初始化
- 当i自增到4时,判断
4 < 4结果为false,循环直接终止,i=4的情况根本不会进入循环体执行arr[i]的访问逻辑,自然不会出现数组越界错误。 - 这里的i完全和for循环开头声明的
var i = 0绑定,不存在未绑定的情况。var声明的变量存在变量提升,会被挂载到当前作用域(这段代码里是全局作用域),整个循环过程操作的都是同一个i变量,只是i=4这个值不会在循环体中被使用。
对应代码:
var arr = [1, 2, 3, 4]; for (var i = 0; i<arr.length; i++){ console.log(arr[i]) }
问题2:连续输出3的运行逻辑
- 核心原因是var声明的变量只有全局/函数作用域,没有块级作用域,且闭包捕获的是变量的引用而非当前值:
- var声明的i会被提升到全局作用域,整个循环过程中所有函数引用的都是同一个全局i变量,不会为每次循环创建独立的i副本。
- 循环执行阶段只是把函数定义赋值给funcs数组,并没有执行函数内部的
console.log代码,此时函数内部的i并没有被求值。 - 循环结束后全局的i已经自增到3,此时再遍历执行funcs中的函数,所有函数访问的都是同一个已经变成3的i,自然会连续输出三次3。
对应代码:
var funcs = []; for (var i = 0; i < 3; i++) { funcs[i] = function() { console.log("My value: " + i); }; } for (var j = 0; j < 3; j++) { funcs[j](); }
内容的提问来源于stack exchange,提问作者nubprog
相关产品推荐
相关产品推荐

