在ES6之前 声明变量只有var ES6之后新增了 let const
下面我们来说说 他们之间的区别
要声明变量,可以使用 var 关键字 后跟一个标识符(即我们说的变量名)比如:
var number = 1;
console.log(number) // 1
一看好像没什么问题,但是你看了另一段代码你就会发现,很奇怪,比如下面的:
console.log(number) // undefined
var number = 1;
console.log(number) // 1
看了上面的代码 是不是觉得很奇怪 明明变量还没声明 打印不应该是报错吗,其实这是应为用var声明的变量会有一个变量提升,var声明的变量会自动提升至当前作用域的顶端,所以你看到的代码应该是这样子的:
var number
console.log(number) // undefined
number = 1;
console.log(number) // 1
正是var声明的变量会存在种种奇怪的行为,所以ES6推出了 let const的变量声明 下面我们来看看他们的区别
作用域不同
函数作用域
var 声明的变量会成为包含它的函数的局部变量,外部访问不到
function test(){
var msg = '我是一个测试内容';
}
console.log(msg) // 错误 'msg is not defined'
可见在函数内部声明的变量外部是访问不到的
变量提升
如上面所说的 var 声明的变量会存在一个变量提升,会把声明提升到当前作用域的顶部
console.log(msg); // undefined
var msg = '这是一个测试';
console.log(msg); // '这是一个测试
用let 声明的变量则不会在作用域中提升
console.log(msg); // 错误 msg is not defined
let msg = '这是一个测试';
使用let 声明的变量 必须是声明后才可以使用,不然就出现暂时性死区
暂时性死区
我们来说一下暂时性死区的概念:虽然JS引擎也会发现let 声明的变量,只不过在let声明之前不能引用该变量,在let声明之前执行的瞬间叫做 "暂时性死区"(temporal dead zone),在此阶段引用后面才声明的变量都会抛出错误
块级作用域
用var 声明的变量是不存在块级的 而let声明的变量则会有块级作用域:
if(true) {
var msg = ' this is test';
}
console.log(msg) // 'this is test'
if(true) {
let msg = ' this is test';
}
console.log(msg) // 错误 msg is not defined
重复声明
var number = 10;
var number = 20;
let age;
let age; // 错误 syntaxError: Identifier 'age' has already been declared
在同一个作用域中 使用var 可以对一个变量重复声明,而let再次声明就会报错
const 声明
const 声明和let 声明差不多, 只不过 const 声明的变量定义了就不能修改值了
let msg = '测试1';
msg = '测试2';
console.log(msg) // '测试2'
const num = 10;
num = 11;
console.log(num) //报错
但是值得注意的一点是如果给变量赋值的是复杂数据类型(或者又叫引用类型)的话则有点不同
const obj = {
name: '小明',
}
obj.age = 18;
console.log(obj); //{ name: '小明', age: 18 }
这次没有报错实际上是因为复杂数据类型赋值给变量的其实是对象内存的引用,实际上是没有修改这个引用的,下面的则会报错
const obj = {
name: '小明',
}
obj.age = 18;
obj = {name:'小兰'}
console.log(obj); //报错
上面的报错是因为本来赋值给obj的引用是指向 { name: '小明'} 这个对象的,而下面的操作是obj的引用指向了obj = {name:'小兰'} 这个对象,内存的引用地址改变了 所以就报错了
以上本人就是对 var let const的理解 如果有不同意见欢迎指出,或者有补充的欢迎push