要理解作用域链,先来回顾下以下知识点:
定义变量的方式:
ES6之前 var
ES6开始 let
两种方式的区别在哪里呢?
通过var定义变量:
- 可以重复定义同名变量,后定义会覆盖先定义的
- 可以先使用后定义(预解析)
- 将定义的变量放到一个单独的{}里面,还是一个全局变量
通过let定义变量:
- 相同作用域内不可以重复定义同名的变量.(重复定义会导致报错)
- 不可以先使用后定义(不会预解析)
- 将定义的变量放到一个单独的{}里面,是一个局部变量
相同点:无论是var 还是let,定义在{}外面都是全局变量
作用域
{}外面的作用域为 全局作用域
函数后面的{}中的作用域为 局部作用域
在ES6中只要{}和函数结合在一起为 块级作用域
作用域链
ES6之前的作用域链
- 全局作用域我们又称之为0级作用域
- 定义函数开启的作用域就是1级/2级/3级...作用域
- Javascript将作用域连接在一起形成一个链条,这个链条就是作用域链
0 ---> 1 ---> 2 ---> 3 ---> 4
ES6开始的作用域链
- 全局作用域我们又称之为0级作用域
- 定义函数或者代码块开启的作用域就是1级/2级/3级...作用域
// 注意与以上不同的是代码块也会开启 - Javascript将作用域连接在一起形成一个链条,这个链条就是作用域链
0 ---> 1 ---> 2 ---> 3 ---> 4
变量在作用域链的查找规则
先在当前作用域链找;如果当前没有找到,依次向上一级作用域中查找;如果直到0级为止都没有找到,就报错.