把let换成var有这么大的区别是为什么呢?
其实这里的唯一差别就是var和let。
二者从用法上来说除了作用域之外别无二致。
对于var来说,他是函数作用域或者全局作用域。 这个取决于var所处的为止,如果在函数内部声明就是函数作用域,如果在全局声明就是全局作用域。
对于let来说,他是块作用域。 它是为数不多的块作用域,其他也有 比如 const 或者 try catch中的 catch中的变量也是块作用域. 和var不同,let定义的变量会”附着“在最近的block,而不是“附着”在最近的函数和script。
对于你这个题来说,let的声明会”附着“在for 的 {} 内部。 而且由于是for, 上述例子其实会声明5个完全不同的变量,尽管变量的名字都是i(就好像函数a里可以有一个i,同时函数b也可以有一个i,互不干扰)。 并且5个变量实际上对应的是不同的值。 而对于var,由于会“附着”到最近的函数或者script,因此实际上只有一个变量,一个变量当然只能有一个值,而不是5个。
That's all the diffrences
这是个块级作用域的问题。for循环中的var声明变量作用域是会溢出到循环体外的,比如
// 第一次循环
var i = 1
if (i <= 5) {
// 执行代码,此时的i是1
i++
}
// 第二次循环
var i = 2
if (i <= 5) {
// 执行代码,此时的i是2
i++
}
...
可想而知,当第五次循环结束,i的值会变成6,异步回调中的变量会全部变成6,因为循环了5次,所以回调函数执行5次
再来看let
声明的变量,它是存在于作用域中,不会消失的,就能得到你想要的依次打印1,2,3,4,5这样的结果。你可以仔细看看阮一峰老师关于let和const命令这章
10 回答11.2k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
因为下边通过var声明的变量i在不同块级作用域内是同一个,上边的let声明的i,在每个块级作用域内都是独立的