var & let & const 的区别
let & const & var
先看下 var 和 let 的的区别
- 变量提升
console.log(a) // undefined
var a = 1
在声明变量a之前输出a,这时候不会报错,而是会输出undefined,我们再来看下let声明变量
console.log(a) // a is not defined
let a = 1
let声明变量没有变量提升所以会报错
- 重复声明
let a = 1
let a = 2 // Identifier 'a' has already been declared
let 声明的变量不可以重复声明,否则会报错
var a = 1
var a = 2
console.log(a) // 2
var 声明的变量可以重复声明,后面的会覆盖前面的
- 块级作用域
{
var a = 1
}
console.log(a) // 1
var 声明的变量没有块级作用域(es6中一个大括号就代表一个块级作用域),可以输出a
{
let a = 1
}
console.log(a) // a is not defined
let 声明的变量有块级作用域,只能在作用域里面调用这个变量,所以会报错
- 给全局对象window增加属性
var a = 1
console.log(window.a) // 1
var 声明的变量会给全局对象window增加属性
let a = 1
console.log(window.a) // undefined
let 声明的变量不会给全局对象增加属性,所以会输出undefined
- 暂时性死区
{
a = 2 // a is not defined
let a = 1
}
因为let 声明的变量存在暂时性死区,所以只能先声明在使用
{
a = 2
var a = 1
console.log(a) // 1
}
var 声明的变量有变量提升,所以不会报错,但是 a = 2 也不会对变量a 进行赋值, 这时候 a 是undefined,所以相当于把 2 赋值给undefined
const
- const 声明一个只读的常量。一旦声明,常量的值就不能改变。
- const的作用域与let命令相同:只在声明所在的块级作用域内有效。
- const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
本质 : 此段复制阮一峰大神。。const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心,下面用个小例子详细说下这段
const a = [1,2]
a.pop()
console.log(a) // [1]
const 声明的是常量,但是它确实改变了,但是没有报错,这是因为数组是引用数据类型, 引用数据类型操作的是引用地址,虽然调用pop方法删除了最后一项,但是始终引用地址没有变,所以不会报错
const a = [1,2]
a = []
console.log(a) // Assignment to constant variable.
当你给常量a 重新赋值一个新数组时,相当于把一个新的引用地址赋值给a, 引用地址改变,就会报错