为何for...in与for...of循环中const声明的变量值看似发生变化?
为什么const能在for...in和for...of循环中"变化"?
这个问题真的戳中了很多人对const的认知误区!其实核心原因是循环的每次迭代都会创建一个独立的块级作用域,而const的特性在这个场景下完全符合规则。
先快速回顾下const的核心规则:
- const声明的变量是块级作用域,和let的作用域特性一致
- 不能对同一个const变量进行重新赋值,也不能重复声明
那回到你给出的示例代码:
const data = ['A', 'B', 'C', 'D']; // 此处const声明的key看似在变化 for (const key in data) { console.log('key ',key); } // 此处const声明的value看似在变化 for (const value of data) { console.log('value ',value); }
1. for...in循环的本质
每次循环迭代时,JavaScript都会创建一个全新的块级作用域,在这个块里声明的const key是一个全新的变量——它不是被重新赋值的旧变量,而是每次都重新声明了一个同名的新const变量,对应当前迭代的属性名。
比如第一次循环的逻辑可以拆解成:
// 迭代1的独立块作用域 { const key = '0'; console.log('key ', key); }
第二次循环则是:
// 迭代2的独立块作用域 { const key = '1'; console.log('key ', key); }
每个key都是完全独立的变量,自然不会违反const“不能重新赋值”的规则。
2. for...of循环同理
for...of的逻辑和for...in完全一致:每次迭代都会生成新的块作用域,const value是在新块里声明的新变量,对应数组当前迭代的元素。每一个value都是独立存在的,不存在“修改同一个const变量”的操作。
反例:真正违反const规则的情况
如果我们尝试在循环外部声明const,然后在循环内赋值,就会直接报错——因为这是在对同一个const变量重复赋值:
const data = ['A', 'B', 'C', 'D']; let key; // 先声明 for (key in data) { console.log('key ',key); } // 正常运行 const fixedKey; for (fixedKey in data) { console.log('key ',fixedKey); } // Uncaught TypeError: Assignment to constant variable.
对比var的差异
如果你用var声明循环变量,就会发现变量是共享的——因为var是函数作用域,整个循环里只有一个变量,每次迭代都会覆盖它的值。这也是为什么const/let在循环里的表现更符合直觉的原因。
内容的提问来源于stack exchange,提问作者Narendra Jadhav
相关产品推荐
相关产品推荐

