【前端八股文面试题】【JavaScript篇8】作用域链介绍?
文章目录
- 作用域链的核心逻辑:
- 作用域链的关键特性:
- 1. 函数定义时确定(词法作用域)
- 2. 作用域的层级结构
- 3. 链的构成单位
- 作用域链 和 闭包
- 总结一张表
在 JavaScript 中,作用域链(Scope Chain)是变量查找的规则链,它决定了代码中如何访问变量和函数。通俗地说,就像你找东西时会按照“由近及远”的顺序搜索不同范围:
作用域链的核心逻辑:
-
从最内层作用域开始查找
当你访问变量时,先看当前函数内部是否有这个变量。function myFunc() {const name = "小明"; // 当前作用域有 → 直接使用console.log(name); // "小明" }
-
逐层向外查找直到全局
如果当前作用域没有,就向上一层父作用域继续找(函数在哪定义,上层作用域就在哪),类似“套娃”式搜索:const globalName = "全局变量";function outer() {const outerName = "外部变量";function inner() {console.log(outerName); // 当前作用域没有 → 找父作用域(outer)console.log(globalName); // outer也没有 → 找全局作用域}inner(); } outer();
-
全局作用域是终点
如果直到全局作用域(浏览器环境是window
)都找不到,报错xxx is not defined
。
作用域链的关键特性:
1. 函数定义时确定(词法作用域)
作用域链在函数创建时就固定了,与在哪里调用无关:
let food = "苹果";function eat() {console.log(food); // 创建时就确定food指向全局
}function kitchen() {let food = "香蕉";eat(); // 输出"苹果"(不是厨房的"香蕉"!)
}
kitchen();
2. 作用域的层级结构
多层嵌套函数的作用域链像倒着的树:
全局作用域└── outer()作用域└── inner()作用域
3. 链的构成单位
- 函数作用域:每个函数都会创建自己的作用域
- 块级作用域(ES6+):用
let/const
时,{}
会创建临时作用域(如if/for
) - 全局作用域:脚本最外层
作用域链 和 闭包
闭包是作用域链的典型应用:当内部函数访问了外部函数的变量,就会形成闭包:
function counterFactory() {let count = 0; // 被内部函数锁在闭包中return function() {count++; // 沿着作用域链找到父函数的countreturn count;};
}const counter = counterFactory();
console.log(counter()); // 1
console.log(counter()); // 2 (count在闭包中存活)
总结一张表
概念 | 类比场景 | JS代码表现 |
---|---|---|
作用域链 | 查找文件:桌面 → 文件夹 → U盘 | 当前作用域 → 父作用域 → 全局 |
词法作用域 | 你的通讯录关系(出生时决定) | 函数定义时固化作用域链 |
闭包 | 带独立储物箱的自动售货机 | 内部函数持有外部变量的引用 |
理解作用域链能帮你避开变量覆盖、命名冲突等问题,也是理解闭包、模块化等高级概念的基础!