在 ES6 中,var、let、const 都可用于变量声明,它们之间有什么区别?在本博客中,详细讲解了 var、let 和 const 的范围、使用和提升。
Var
在 ES6 之前,我们 一般使用 var 声明遍历。但是,使用 var 声明的变量存在一些问题,所以才导致了 let、const 的出现。
var 的作用域
作用域
表示着这些变量可以在哪里使用。var
声明的作用域是全局的、或者是函数内部的。
- 如果我们在函数外部声明
var
变量,那么它的作用域是全局的。 - 如果在函数中声明
var
,那么它的作用域是在函数内部。换句话说,只能在函数内使用该变量,当函数执行完毕,该变量将会被回收。
可以通过以下例子体会一下
var a = "codereasy";
function newFunction() {
var b = "hi";
}
在上面的例子中,a
是全局作用域 ;而 b
是函数作用域,所以我们只能在函数内部访问变量 b
。如果我们强行在函数外部访问b
,会发生什么?
var a = "codereasy";
function newFunction() {
var b = "hi";
}
console.log(b)// error: b is not defined
会报错,提示 b 没有被定义。因此,不能在函数外部访问b
。
var 可以重复声明
var x = 1;
var x = 2; // 重新声明变量 x,覆盖之前的值
console.log(x); // 输出 2
var 变量提升
var
声明的变量存在变量提升,即变量可以在声明前使用。但其值为 undefined
。在全局作用域,或者在函数中,变量可以在声明前使用,而不会抛出 ReferenceError
异常。例如下面的代码:
function example() {
console.log(foo); // undefined
var foo = "Hello, world!";
}
var 存在的问题
var a = "codereasy";
var times = 4;
if (times > 3) {
var a = "haha";
}
console.log(a) // "haha"
由于 times > 3
返回 true,a
被重新定义为 "haha"
。如果,你忘记其他同事曾经定义过一个变量 a
,现在无意间修改了 a
的值,那么在今后使用 a
的值时,已经是修改后的值了。
Let
let
现在已经基本代替了 var
,它对 var
进行了改进。
let块级作用域
首先理解什么是块级作用域?块是由{ }
包裹起来的代码。换句话说,被一对花括号包起来的代码,都属于一个块。
所以,用 let
声明的变量只能在它所在的块中使用,比如以下例子:
let times = 4;
if (times > 3) {
let a = "codereasy";
console.log(a);// "codereasy"
}
console.log(a) // a is not defined
通过以上例子我们发现,在它的块(花括号)之外使用 a
会返回一个错误。这是因为 let
变量是块作用域。
let不能被重新声明
首先,使用 let
声明的变量可以在其作用域内更新。但是与 var
不同的是,let
变量不能在其作用域内重新声明。比如下面的例子:
let a = "codereasy";
a = "hahahaa"; //这没问题,因为let可以被更新
如果重新声明,就会报错:
let a = "codereasy";
let a = "hahahaa"; error: Identifier 'a' has already been declared
不过,如果在不同的作用域,重复声明 let
不会报错。
let a = "codereasy";
if (true) {
let a = "say Hello instead";
console.log(a); // "say Hello instead"
}
console.log(a); // "codereasy"
为什么现在没有报错?这是因为两个 a
本质上是不同的变量,因为它们在不同的作用域。codereasy
在全局作用域,而 say Hello instead
在花括号内部的作用域。
所以,就不出现之前 var
导致的错误了。使用 let
时,如果你以前使用过该变量名,只要它们不在同一个作用域,就互不影响。另外,你不用担心不小心修改了别人定义的变量,因为重复声明会报错。
let变量提升
let
声明会被提升到本作用域的顶部。但和 var
不同,let 关键字未初始化。所以,如果在声明之前使用 let
变量,会报错 Reference Error
。
Const
const
的声明类似于 let
的声明。
const声明是块级作用域
const
声明的变量只能在它所在的块内访问。
const不能被更新也不能重新声明
如果更新,会报错:
const a = "codereasy";
a = "codereasy";// error: Assignment to constant variable.
如果重新赋值,也会报错:
const a = "codereasy";
const a = "codereasy";// error: Identifier 'a' has already been declared
虽然不能更新、重新声明 const
变量,但是我们可以修改 const
对象的属性:
const student = {
name: "codereasy",
age: 18
}
student = {
words: "Hello",
number: "five"
} // error: Assignment to constant variable.
上面代码会报错,因为我们直接修改了 const
变量。但是下面代码不会报错:
student.age = 99;
我们并没有直接修改 const
变量,只是修改了这个对象的属性,因此没有报错。
const变量提升
和 let
一样,const
声明被提升到顶部,但没有被初始化。因此,在声明之前使用 const
变量,会报错Reference Error
总结
var
声明的变量,其作用域是全局作用域或函数作用域,而 let
和 const
是块作用域。
var
可以在被更新和重新声明;let
变量可以更新但不能重新声明;const
变量既不能更新也不能重新声明。
在变量提升方面,它们都被提升到了作用域的顶部。但是,var 变量会被初始化为 undefined
, let
和 const
不会被初始化。
var
和 let
在声明的时候,不一定需要初始化(换而言之,你可以不赋值仅声明 let a
),而 const
必须在声明时初始化。