区别
- var
存在变量提升;全局变量;可重复声明变量,可重新赋值; - let
不存在变量提升;局部变量(作用域内有效);不可重复声明变量;不能重新赋值 - const
不存在变量提升;局部变量(作用域内有效);不可重复声明变量,不可重新赋值(声明时必须赋值);
let
1. 基本用法
let 声明的变量只在代码块内有效,也就是花括号内, var声明的变量全局生效,所以var容易污染全局变量,定义变量的时候 一般使用let
{
let a = 0
var b = 1
}
console.log(a) // Uncaught ReferenceError: a is not defined
console.log(b) //1
2. 不可重复声明/不能重新赋值
使用let声明变量的时候,不能重复声明,也就代表着在函数体内部不能再使用let声明形参,也会报错
{
let a = 10
let a = 0
}
function func(a) {
let a; // 报错
}
//Identifier 'a' has already been declared
3. 不存在变量提升
不存在变量提升的字面意思 大概就是必须先声明变量,再使用变量
console.log(a)
let a = 0 // Cannot access 'a' before initialization
用var命令声明,会发生变量提升,即脚本开始运行时,变量已经存在了,但是没有值,所以会输出undefined。用let命令声明,不会发生变量提升。这表示在声明它之前,变量是不存在的,这时如果用到它,就会抛出一个错误。
const
const有很多属性都与let一样,但是const声明的变量是不可更改的,而且一旦使用const声明后就必须赋值
面试题
for(var i=0; i<5; i++){
setTimeout(()=> {
console.log(i);
},1000)
} //55555
for(let i=0; i<5; i++){
setTimeout(()=> {
console.log(i);
},1000)
} //0 1 2 3 4
解析:上面代码1中,变量i使用var声明,var声明的是全局变量,全局只有一个i变量,所以,每次循环对i重新赋值,所以定时器里面的i指向的都是全局的同一个i,导致执行定时器的时候,输出的都是最后一轮的值,也就是5
对于let声明的变量来说,i只在当前循环内有效 ,也就是每次循环都创建了一个作用域,里面的i是单独的,所以最后循环出来是0 1 2 3 4
另外,for循环中设置循环变量的部分是父作用域,循环体内部是单独的子作用域,下面函数输出了3个aaa表名函数内部的变量i与循环变量i不在一个作用域,各有各的单独作用域
for (let i = 0; i < 3; i++) {
let i = 'aaa'
console.log(i)
}
//aaa aaa aaa