let 和 const
let
- let 声明的成员只会在所声明的块中生效
如果使用 var 声明变量,可以正常输出,var 关键字有变量提升的过程
if (true) {
var foo = 'foo'
console.log(foo)
}
console.log(foo)
如果使用 let 声明变量,外层调用就会报错
if (true) {
let foo = 'foo'
console.log(foo)
}
// ReferenceError: foo is not defined
console.log(foo)
- let 在 for 循环中的表现
如果使用 var 声明
for (var i = 0; i < 3; i++) {
for (var i = 0; i < 3; i++) {
console.log(i)
}
console.log('内层结束 i = ' + i)
}
// 0
// 1
// 2
// 内层结束 i = 3
如果使用 let 声明,能正常的得到想要的 9 次输出
for (let i = 0; i < 3; i++) {
for (let i = 0; i < 3; i++) {
console.log(i)
}
console.log('内层结束 i = ' + i)
}
// 0
// 1
// 2
// 内层结束 i = 0
// 0
// 1
// 2
// 内层结束 i = 1
// 0
// 1
// 2
// 内层结束 i = 2
- let 应用场景:循环绑定事件,事件处理函数中获取正确索引
使用 var 作为循环声明
var elements = [{}, {}, {}]
for (var i = 0; i < elements.length; i++) {
elements[i].onclick = function () {
console.log(i)
}
}
elements[1].onclick()
// 不管调用哪一个事件,输出都是3
使用闭包来解决变量提升的问题
var elements = [{}, {}, {}]
for (var i = 0; i < elements.length; i++) {
elements[i].onclick = (function (i) {
return function () {
console.log(i)
}
})(i)
}
elements[1].onclick()
使用 let 可以避免这种问题
var elements = [{}, {}, {}]
for (let i = 0; i < elements.length; i++) {
elements[i].onclick = function () {
console.log(i)
}
}
elements[1].onclick()
- for 循环中有两层作用域
for (let i = 0; i < 3; i++) {
let i = 'foo'
console.log(i)
}
// foo
// foo
// foo
// for 循环类似代码
let i = 0
if (i < 3) {
let i = 'foo'
console.log(i)
}
i++
if (i < 3) {
let i = 'foo'
console.log(i)
}
i++
if (i < 3) {
let i = 'foo'
console.log(i)
}
i++
- let 修复了变量声明提升现象
console.log(foo)
var foo = 'foo'
console.log(foo1)
let foo1 = 'foo1'
// var 输出
// undefined
// let 输出
// ReferenceError: Cannot access 'foo1' before initialization
const
const 声明的变量不允许重新赋值
const name = 'name'
name = 'name1'
// TypeError: Assignment to constant variable.
const 声明的变量要求声明并且同时赋值
const name
name = 'name'
// SyntaxError: Missing initializer in const declaration
const 声明只是要求指向不允许被改变,但是可以修改数据内成员
const obj = {}
obj.name = 'name'
console.log(obj)
obj = {}
// { name: 'name' }
// TypeError: Assignment to constant variable.
let 和 const 注意
- let 和 const 声明的变量,在全局作用域下不会被挂在到全局对象中,浏览器为 window,node 为 global
- ReferenceError 引用错误与暂存死区
let 和 const 一致
console.log(b) // Uncaught ReferenceError: b is not defined
// 以上的区域为暂存死区
let b = 1