在没有ES6之前,只有一种方式定义变量的方法,就是var。
但是用var定义的变量会导致变量提升,导致使用之前就被定义了
console.log(a); //undefined;
var a = 10;
用var定义有什么缺点
- 会导致变量提升,导致定义之前可以使用
- 会导致全局污染
- 允许重复声明
for(var i=0;i<10;i++) {
};
console.log(i); //10
ES6的出现恰恰可以解决这两个问题
ES6有两种方式定义变量:let和const
我们先说let定义变量有什么优点
优点
- 没有变量提升
- 不会导致全局污染
- 不允许重复声明
如果是使用let来定义变量,在定义变量之前使用,会报错
//(未捕获的ReferenceError:在初始化之前无法访问“num” )
console.log(num);
let num = 10;
在let中,是不允许重复声明变量
//不能重新声明块作用域变量“num”
let num = 10;
let num = 20;
在ES6,为什么没有变量提升,为什么ES6要这样规定,有什么好处
首先,我们先认识一个东西,叫做暂时性死区(TDZ),暂时性死区限制了变量范围,防止变量声明之前被使用,这样的好处就是主要减少运行时的错误,导致一些意料之外的行为
借助之前那个例子,之前的例子,num变量是先存放在暂时性死区(TDZ)里,解除暂时性死区的方法,就是不要在定义变量之前使用。
//(未捕获的ReferenceError:在初始化之前无法访问“num” )
console.log(num);
let num = 10;
下面的例子,num就解除了暂时性死区,就可以访问到对应变量的值
let num = 10;
console.log(num); // 10
接下来,讲解const定义变量
先说优点
1、和let一样,没有变量提升,不能重复声明
2、赋值之后,不能被修改
const定义之后不能修改值(注意:这里的不能修改是指保存的内存地址,不是指变量存储的值)
const a = 20;
console.log(a);
a = 30;
/*
未捕获的类型错误:对常量变量的赋值
Uncaught TypeError: Assignment to constant variable.
*/
console.log(a);
验证上一个例子,这里说的不能改变,是值变量存储的内存地址不能改变,但内存中存储的值是可以改变的
const obj = {
num: 10
}
console.log(obj.num); //10
obj.num = 100;
console.log(obj.num); //100
还有另一点我需要补充说明一下:在块级作用域中,不建议使用函数声明函数,因为一旦使用了函数声明,函数就会提升在块级作用域顶部,建议优先使用函数表达式,函数表达式只是一个变量赋值的操作,没有函数提升的特性。