在解释什么是作用域链前先来看一段代码:
<script>// 全局作用域let a = 1;let b = 2;// 局部作用域function f() {let c;// 局部作用域function g() {let d = 'yo';}}</script>
函数内部允许创建新的函数,f 函数内部创建的新函数 g,会产生新的函数作用域,由此可知作用域产生了嵌套的关系。
如下图所示,父子关系的作用域关联在一起形成了链状的结构,作用域链的名字也由此而来。
作用域链本质上是底层的变量查找机制,在函数被执行时,会优先查找当前函数作用域中查找变量,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域,如下代码所示:
<script>// 全局作用域let a = 1;let b = 2;// 局部作用域function f() {let c;// let a = 10;console.log(a); // 1 或 10console.log(d); // 报错// 局部作用域function g() {let d = 'yo';// let b = 20;console.log(b); // 2 或 20}// 调用 g 函数g()}console.log(c); // 报错console.log(d); // 报错f();</script>
总结:
- 嵌套关系的作用域串联起来形成了作用域链
- 相同作用域链中按着从小到大的规则查找变量
- 子作用域能够访问父作用域,父级作用域无法访问子级作用域(就近原则)
