前言
都是自己总结的知识,有什么不对的地方请指出,大家一起讨论学习
一、什么是作用域?
在说ES6的时候,先说说什么是作用域。
作用域:
简单地说,就是作用的范围是有规定的,指它在函数在哪些范围内可以用,而在其他部分不可以,要用就得重新定义,如果你强行使用,编译时候就报错,无法通过编译。
举一个ES6的js例子说明,因为ES6最大的区别就增加一个块作用域(其实这个作用域的意思在其他开发语言都是差不多的):
<script>
//全局变量
let a1 = "a1";
//块区域
if(true) {
// 块区域变量
let a2 = "a2";
console.log("a2:" +a2);
}
console.log("a1:" +a1);
console.log("a2:" +a2);
</script>
我们看看输出结果,最后的a2输出是报错:“未定义a2”,这时候我们就会想为什么在括号里面是可以用的,在外面就不能用,这个就是我们编程语言的作用域,a2的作用域只在括号里面,你在外面要使用就会报错。
a2:a2
a1:a1
Uncaught ReferenceError: a2 is not defined
二、ES5与ES6的作用域有什么区别
ES5 只有全局作用域和函数作用域,没有块级作用域。
ES6除了全局作用域和函数作用域,增加块级作用域。
三、let变量
ES6 新增了let命令,用来声明变量。它的用法类似于var,但是let所声明的变量,只在let命令所在的代码块内有效。
1.1 基本使用
直接使用变量名定义变量,然后就可以使用了这个变量
<script>
var a = "1";
let a1 = "a1";
</script>
1.2 let的不同之处
let有块级作用域,而var没有块级作用域,我们在使用的时候就发现这个,a变量不能使用,出现报错,b可以正常使用。就是因为他们两个的作用域不一样的原因
<script>
if (true) {
let a = 10;
var b = 1;
}
</script>
a // ReferenceError: a is not defined.
b // 1
1.3 let不存在变量提升
变量提升的意思就是没有定义之前就可以使用,只是变成了undefined
var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。对于我们这种习惯命令式编程的人来说,这个现象是超级奇怪,脑子都会有一个为什么能这样操作,但是实际开发中,大家都会先定义好变量在使用,只是我们没留意这个问题而已。
为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错,这也大大给我们定位问题减少很多麻烦。
<script>
// var 的情况
console.log(a); // 输出undefined
var a= 2;
// let 的情况
console.log(b); // 报错ReferenceError
let b= 'b';
</script>
1.4 暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”这个区域,不再受外部的影响。
就下面例子说明,先定义了全局变量var a,然后在if的块里使用这个a变量,但是块里又定义了一个let a变量,这时候,块里的变量let a已经和这块绑定了,就是以块里let a为主,你要使用a变量就要在声明之前使用,不然就报错,这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
<script>
var a= 123;
if (true) {
a= 'a'; // ReferenceError
let a;
}
</script>
1.5 不允许重复声明
let不允许在相同作用域内,重复声明同一个变量。
<script>
let a= 123;
let a= 123;//报错,变量已经被声明
if (true) {
let b= 123;
let b= 123;//报错,变量已经被声明
}
</script>
总结
主要就是了解ES6的块级作用域的问题,ES6新增的let是有块级作用域,而ES5的var没有块级作用域