在js中,通用定义变量一般会使用var命令,而es6中新增了let和const两种命令来定义变量。使用let, const命令,它的优势在哪里,两者之间区别是什么,有哪些需要注意的地方。
1. let命令
1.1 块级作用域
js中作用域一般有全局作用域,函数作用域,而let命令实际上给js新增了块级作用域。
function demo () {
let a = 1
if (true) {
let a = 2;
}
console.log(a); // 1
}
demo();
上面的函数有两个代码块,都声明了变量a,运行后输出1。这表示外层代码块不受内层代码块的影响。如果两次都使用var定义变量a,最后输出的值才是2。
1.2 不存在变量提升
function demo() {
console.log(a);
let a = 1;
}
demo(); // a is not defined
上面函数中提示ReferenceError: a is not defined. 使用let命令,不会如var命令一样,存在变量提升。
1.3 不能允许重复声明
function demo() {
let a = 1;
let a = 2;
}
demo(); // error 'a' has alreedy been declared
1.4 暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”这个区域,不再受外部的影响
var a = 123;
function demo() {
if (true) {
a = 'abc'; // ReferenceError a is not defined
let a;
}
}
demo();
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”。
2. const命令
const命令声明只读常量, 一旦声明,就不能改变.
function demo() {
const a = 1;
a = 2; // ReferenceError
}
demo();
同理,const和let命令一样,也同样存在块级作用域,不能重复声明,声明变量不能提升,存在暂时性死区。
const声明变量,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于对象和数据类型,变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。
const obj = {}
obj = {} // TypeError
function demo() {
const obj = {};
obj.name = 'xiaoming'; // 添加属性或改变属性可以的
}
demo()
注意点
let命令、const命令声明的全局变量,不属于顶层对象的属性。也就是说,从ES6开始,全局变量将逐步与顶层对象的属性脱钩。
let a = 1;
window.a // undefined