专栏名称: 众成翻译
翻译,求知的另一种表达
目录
相关文章推荐
资本时差  ·  你闭嘴吧!说得你比我还有钱似的。 ·  昨天  
杭州网  ·  刚刚,阿里重磅宣布! ·  昨天  
杭州网  ·  刚刚,阿里重磅宣布! ·  昨天  
ETF和LOF圈  ·  大会在即 市场积极 ·  2 天前  
人生资本论  ·  别等了,风向果然变了 ·  2 天前  
人生资本论  ·  罕见!国家下狠心,拼命稳住外资 ·  2 天前  
51好读  ›  专栏  ›  众成翻译

JavaScript循环和作用域

众成翻译  · 掘金  ·  · 2018-09-04 11:03

正文

JavaScript 有一个特点,也许会让开发者头痛, 是与循环和作用域相关的.

举个例子:

const operations = []

for (var i = 0; i < 5; i++) {
  operations.push(() => {
    console.log(i)
  })
}

for (const operation of operations) {
  operation()
}


它基本是循环了5次,将一个函数添加到operations数组里面。这个函数可打印出循环变量索引值 i .

运行这些函数后

期望的结果应该是:

0
1
2
3
4


但实际发生的是这样的:

5
5
5
5
5


为什么会有这种情况? 因为使用的是 var .

由于 提升 var 变量, 上面的代码等同于

var i;
const operations = []

for (i = 0; i < 5; i++) {
  operations.push(() => {
    console.log(i)
  })
}

for (const operation of operations) {
  operation()
}


因此,在for-of循环中, i 依然是可见的, 它等于5,并且每次在函数中涉及到 i ,都将使用这个值。

那么我们应该如何做让其变成我们想的这样呢?

最简单的方案是用 let 声明. 在ES2015中介绍到, 它们有很大的帮助,能避免关于使用 var 声明的一些奇怪问题。

简单的在循环变量时将 var 变成 let ,能够很好的运行:

const operations = []

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

for (const operation of operations) {
  operation()
}


这是输出结果:

0
1
2
3
4


这是怎么实现的呢?这是因为每次循环重复的时候,都将重新创造 i ,同时每个函数添加 operations 数组时,能获取它本身的 i

记住你不能使用 const 在这种情况下, 因为这会导致 for 在第二次循环时, 尝试赋新值报错。







请到「今天看啥」查看全文


推荐文章
杭州网  ·  刚刚,阿里重磅宣布!
昨天
杭州网  ·  刚刚,阿里重磅宣布!
昨天
ETF和LOF圈  ·  大会在即 市场积极
2 天前
人生资本论  ·  别等了,风向果然变了
2 天前
人生资本论  ·  罕见!国家下狠心,拼命稳住外资
2 天前
经典短篇阅读小组  ·  几番风雨,匆匆春又归去
7 年前