一,var
- 用var声明的变量是函数作用域(在函数内部声明的变量只能在函数作用域内部使用,在函数外部不能访问。但是,在函数内部可以访问函数外部的全局作用域中的变量。)
- var声明的变量会有变量提升(在var 之前就可以使用,未赋值时是undefined)
- 全局作用域中的var声明的变量是挂载在全局对象windows上
- 在同一作用域下,var可以声明相同名字的变量
二, let
- 用let声明的变量是块级作用域下的(块级作用域是用{}来界定的,块与块之间不能访问变量)
- 用let声明的变量没有变量提升(也就是说,在使用之前必须声明)
- 在全局作用域下,用let声明的变量不会挂载在全局对象windows上的
- 在同一作用域下,let不能重复声明名字相同的变量
三,const用来声明常量
- 作用域也是块级的
- 用const声明的常量必须要赋值,不然会报错
- 用const声明的常量不能改变值
一个let的例子:一秒后打印0,1,2,3,4
使用var:
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 10);
}
解决1:使用立即执行函数形成闭包,这里自执行函数fn在每次循环的时候,都会创建一个全新的执行上下文。各个执行上下文之间不会相互影响,从而保证每次传入的i不会发生变化。
for (var i = 0; i < 5; i++) {
(function fn(i) {
setTimeout(() => {
console.log(i);
}, 1000);
})(i);
}
解决2:使用let(其实现过程其实和上例中的自执行函数形成闭包,并将对应的变量传入类似,只不过传入变量并赋值的过程JavaScript引擎帮我们处理了。)
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
}, 10);
}
|