let 和 const 关键字是 ES6 的新语法,主要用来取代 var 来定义变量。ES6 出了这么一个简单的新语法其实足以说明JS有很多不好的地方,而其中之一就是变量声明。
var
以前我们声明变量一般用var a= 1,但是会带来很多不好的副作用。
变量的提升
参考下面的代码
function fn() {
if (true) {
console.log(a + ' now')
}
else {
var a = 1
console.log(2)
}
}
fn() // a -> undefined
我们发现不执行的代码也会影响会执行的代码,因为var a会提升到if语句的前面,改写后会变成。
function fn() {
var a
if (true) {
console.log(a + ' now')
}
else {
a = 1
console.log(2)
}
}
fn() // a -> undefined
全局变量
在以前的JS版本中,作用域只能是函数作用域才有效。
var a = 1 // 声明全局变量 a = 1
为了不使用全局变量,我们一般使用立即执行函数来包住局部变量。
!function() {
var a = 1 // 声明了一个非全局变量
window.frank = function () {
console.log('Now: ' + a)
}
}()
frank()
let
let 和 const 的出现解决了上面的两个问题。
不存在变量提升
{
console.log(a) // undefined
let a = 1
}
变量a不会在console.log(a)之前声明。console.log(a)将会打印出undefined,因为a是在后面才声明的,我们将console.log(a)这个区域称为临时死区。
临时死区听起来感觉很高大上,其实只是访问了还未声明的变量的代码区域罢了。
块级局部变量
{
let a = 1
}
console.log(a) // undefined
这里的a就是块级里的变量,块级外不能被访问。
const
const 的特性和 let 完全一样,不同的只是
- 只能进行一次赋值
- 声明时候必须赋值
const a
a = 1 // Missing initializer in const declaration
const a = 1
a = 2 // Assignment to constant variable
总结
let
-
let的作用域在最近的 {} 之间 - 如果你在
let a之前使用变量a,那么报错 - 如果你重复
let a,那么报错
const
- 1.2.3 同上
- 只有一次赋值机会,不能只声明不赋值,必须在声明的时候立马赋值
面试题
简单的Demo
for (let i = 0; i < 5; i++) {
console.log(i)
}
上面的代码我们知道打印结果是 0, 1, 2, 3, 4,但是你们有没有想过这个变量i的作用域到底是什么呢?
有人说在这个for循环里呀,但是我这里想说的是这个i作用域是在括号()里。正常的代码是这样的:
- 首先这个变量
_i的作用域是在()里才有效的,循环体里是不能访问到_i的 - 每次循环的时候创建一个
i变量,将括号里的_i赋值到变量i上 - 最后
i++后再将变量i的值赋值回_i上
当然这个过程是很复杂的,可以用下面代码理解,但是JS的实现机制是很复杂的,这里想要说明的let i的作用域有时候并不是我们所理解的那样的。
for (let _i = 0; i < 5; i++) {
let i = _i
console.log(i)
// i++ 先做
_i = i
}








网友评论