前言
var、let、const 都是 JavaScript 中声明变量的方式,其中 let、const 是在 ES6/ES2015 中新引入的
它们之间究竟有什么异同呢?下面让我们一起来探讨一下
正文
1、作用域
使用 var 声明的变量具有函数作用域
如果变量是在函数内声明的,那么这个变量在这个函数内可用
如果变量是在函数外声明的,那么这个变量就会成为全局变量,在全局环境中可用
并且在浏览器环境中将会挂载在 window 对象下,而在 Node 环境中将会挂载在 global 对象下
var a = 0 function func() { for (var i = 1; i <= 5; i++) { a = a + 1 } console.log('a inside the function: ' + a) console.log('i inside the function: ' + i) } func() console.log('a outside the function: ' + a) // console.log('i outside the function: ' + i) -> i is not defined /* * 执行结果: * a inside the function: 5 * i inside the function: 6 * a outside the function: 5 **/
使用 let 和 const 声明的变量具有块作用域
- 如果变量是在块内声明,那么仅在块内可用
- 如果变量是在块外声明,那么这个变量也会成为全局变量,在全局环境中可用,但是不会挂载
let a = 0 function func() { for (let i = 1; i <= 5; i++) { a = a + 1 } console.log('a inside the function: ' + a) // console.log('i inside the function: ' + i) -> i is not defined } func() console.log('a outside the function: ' + a) // console.log('i outside the function: ' + i) -> i is not defined /* * 执行结果: * a inside the function: 5 * a outside the function: 5 **/
补充一点,如果在声明变量的时候没有使用关键字(var、let、const),无论位置如何,都会成为全局变量
function declare() { a = 'Hello' } function use() { console.log(a) } declare() use() /* * 执行结果: * Hello **/
2、变量提升
使用 var 声明的变量会将声明提前(注意赋值不会一起提前),但是使用 let 和 const 声明的变量不会
console.log(a) var a = 1 console.log(b) let b = 1 /* * 执行结果: * undefined * Uncaught ReferenceError: a is not defined **/
3、同名变量
使用 var 声明的变量可以多次声明,但是使用 let 和 const 声明的变量不能
var a = 0 var a = 1 let b = 0 let b = 1 /* * 执行结果: * Uncaught SyntaxError: Identifier 'b' has already been declared **/
4、只读引用
从上面的三组对比可以发现,let 和 const 具有一样的特点,那么它们之间又有什么区别呢?
事实上,除了它们共有的特点外,const 还具有以下两个特点:
一旦声明,必须赋值
一旦声明,不能修改
// const a -> Uncaught SyntaxError: Missing initializer in const declaration const a = 0 // a = 1 -> Uncaught TypeError: Assignment to constant variable.
注意哦,这里所说的不能修改,并不是说变量的值不可修改,而是变量的标识符不能重新分配
准确而言,const 声明的变量是一个值的只读引用,它意味着栈空间的地址不可修改,而非堆空间中的值不可修改
因此对于引用类型,我们还是可以修改它的值的
const a = [1, 3, 5] a[0] = 2 // 修改其值 console.log(a) /* * 执行结果: * (3) [2, 3, 5] **/