怎么理解javascript作用域链_javascript中如何查找变量
发布时间 - 2026-01-05 00:00:00 点击率:次作用域链是JavaScript中变量查找的单向链表路径,由函数定义时的词法环境决定,逐级向上查找至全局环境;闭包使外层词法环境持久化,let/const存在TDZ,eval和with会动态修改链且应避免使用。
作用域链本质是嵌套作用域的查找路径
JavaScript 中变量不是“全局搜索”,而是沿着当前执行上下文的作用域链一级级向上找。这条链由函数定义时的词法环境决定,和函数在哪调用无关。每次进入函数,引擎会把该函数的 [[Environment]](内部属性)连到外层作用域的 LexicalEnvironment 上,形成一条单向链表。
变量查找过程:从当前作用域开始逐级向上
查找变量时,JS 引擎按以下顺序进行:
- 先查当前执行上下文的
LexicalEnvironment(含let/const声明和函数参数) - 没找到就查其
outer引用(即外层函数的词法环境) - 继续向上,直到全局环境(
globalThis或window) - 全程找不到就抛出
Refe
renceError
注意:var 声明会被提升并绑定到函数作用域(或全局),但查找逻辑仍走同一链条;let/const 有暂时性死区(TDZ),未初始化前访问会报 ReferenceError,不是“找不到”而是“不可访问”。
闭包让外层作用域持久化,改变作用域链生命周期
当一个函数返回了内部函数,且该内部函数引用了外层变量,外层词法环境不会被销毁——它被保留在返回函数的 [[Environment]] 中。这意味着作用域链在函数调用结束后依然存在。
立即学习“Java免费学习笔记(深入)”;
function outer() {
const x = 42;
return function inner() {
console.log(x); // x 在 outer 的 LexicalEnvironment 中
};
}
const fn = outer();
fn(); // 仍能访问 x —— outer 的作用域链被 inner 持有
常见误判点:
-
for (var i = 0; i console.log(i), 0); }输出三个3:因为所有回调共享同一个var i,它属于outer函数作用域,循环结束时值为3 - 换成
let i就输出0,1,2:每个迭代创建独立绑定,每个回调闭包指向各自块级环境
eval 和 with 会动态修改作用域链,应避免使用
eval 在非严格模式下可向当前作用域注入变量,导致作用域链临时扩展;with 会把传入对象作为新的最内层作用域插入链首。两者都破坏静态可分析性,影响 JIT 编译优化,且极易引发意外覆盖。
例如:
function f() {
const a = 1;
with ({ a: 2 }) {
console.log(a); // 2 —— 不是从词法上确定的 a,而是运行时查 with 对象
}
}
V8、SpiderMonkey 等现代引擎对含 with 或非严格 eval 的函数直接禁用优化,性能断崖式下降。ES5 起严格模式已禁止 with,也限制 eval 的作用域污染能力。
真正难理解的不是“怎么找”,而是“找谁”——取决于函数定义的位置,而不是调用的位置;而最容易被忽略的,是 let 绑定的块级环境如何被闭包捕获、以及 TDZ 如何让“存在但不可读”成为常态。
# javascript
# java
# js
# win
# 作用域
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
音乐网站服务器如何优化API响应速度?
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
怎么用AI帮你为初创公司进行市场定位分析?
使用C语言编写圣诞表白程序
googleplay官方入口在哪里_Google Play官方商店快速入口指南
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
Java解压缩zip - 解压缩多个文件或文件夹实例
如何在阿里云高效完成企业建站全流程?
微信小程序 HTTPS报错整理常见问题及解决方案
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
如何快速启动建站代理加盟业务?
laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门
如何破解联通资金短缺导致的基站建设难题?
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
Edge浏览器如何截图和滚动截图_微软Edge网页捕获功能使用教程【技巧】
南京网站制作费用,南京远驱官方网站?
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
高性能网站服务器配置指南:安全稳定与高效建站核心方案
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程
如何在建站之星绑定自定义域名?
如何打造高效商业网站?建站目的决定转化率
个人摄影网站制作流程,摄影爱好者都去什么网站?
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
nginx修改上传文件大小限制的方法
C语言设计一个闪闪的圣诞树
Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程
详解vue.js组件化开发实践
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
Laravel如何与Inertia.js和Vue/React构建现代单页应用
如何在IIS中配置站点IP、端口及主机头?
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
公司网站制作需要多少钱,找人做公司网站需要多少钱?
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
Laravel如何处理表单验证?(Requests代码示例)
如何快速生成可下载的建站源码工具?
如何用wdcp快速搭建高效网站?
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
图册素材网站设计制作软件,图册的导出方式有几种?
如何用y主机助手快速搭建网站?
Laravel如何与Docker(Sail)协同开发?(环境搭建教程)
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?


renceError