区别
var | let | const | |
---|---|---|---|
重复定义 | √ | × | × |
修改值 | √ | √ | × |
声明提升 | √ | × | × |
块作用域 | × | √ | √ |
循环 | √ | √ | × |
重复定义
// 重复定义 var
var cat = 'amao'
var cat = 'agou'
console.log(cat) // 不报错,输出 agou
// 重复定义 let
let dog = 'wangcai'
let dog = 'laifu'
console.log(dog) // Uncaught SyntaxError: Identifier 'dog' has already been declared
// 重复定义 const
const rat = 'jerry'
const rat = 'mickey'
console.log(rat) // Uncaught SyntaxError: Identifier 'rat' has already been declared
修改值
// 修改 var 值
var cat = 'amao'
cat = 'agou'
console.log(cat) // 输出 agou
// 修改 let 值
let dog = 'wangcai'
dog = 'laifu'
console.log(dog) // 输出 laifu
// 修改 const 值
// 常量当然不能被修改
const rat = 'jerry'
rat = 'mickey'
console.log(rat) // Uncaught TypeError: Assignment to constant variable.
// 但也不一定
// 若为引用类型,则可以修改
// 此时的 const 仅仅代表指向引用类型地址的指针
const animals = ['cat', 'dog', 'rat']
animals.push('duck')
声明提升
cat = 'Tom'
var cat
console.log(cat) // 输出 Tom 可以提升
// let 不能声明提升
// 报错 Uncaught ReferenceError: Cannot access 'dog' before initialization
dog = 'laifu'
let dog
console.log(dog)
// const 在声明时就要赋值
// 报错 Uncaught SyntaxError: Missing initializer in const declaration
rat = 'mickey'
const rat
console.log(rat)
// 正确测试 const 能否声明提升
// 报错 Uncaught ReferenceError: Cannot access 'rat' before initialization
console.log(rat)
const rat = 'mickey'
块级作用域
{
var cat = 'Tom'
let dog = 'Wangcai'
const rat = 'Jerry'
}
// 打印 Tom
console.log(cat)
// let 不能跳出块级作用域被使用
// 报错 Uncaught ReferenceError: dog is not defined
console.log(dog)
// 同理 const 也不能
// 报错 Uncaught ReferenceError: dog is not defined
console.log(rat)
循环
// const 不能修改值 不考虑
// var
// 由于 var 并不能形成块级作用域,因此,在 for 循环执行时
// 函数创建时的执行期上下文并不保存当前 i 值
// 函数调用时只能沿着作用域链找到 window 上的 i 进行打印输出
var arr = []
for (var i = 0; i < 3; i++) {
arr[i] = function () {
console.log(i)
}
}
arr[0]() // 3
arr[1]() // 3
arr[2]() // 3
- 如图,在函数的作用域链中,并没有块级作用域,只有全局作用域
// let
// 每次循环 let 会形成当前的块级作用域,从而保存当前的 i 值
// 函数执行时,沿着作用域链在保存好的块级作用域中,找到了 i
var arr = []
for (let i = 0; i < 3; i++) {
arr[i] = function () {
console.log(i)
}
}
arr[0]() // 0
arr[1]() // 1
arr[2]() // 2