网站首页 > 技术文章 正文
作为 js 基础知识的 三座大山之一的闭包和作用域,一直是前端笔面试中常考的知识点。
基于作用域和闭包的笔试题是层出不穷,今天让我们抽丝剥茧,透过现象看本质,从两个小案例去加深闭包和作用域的理解。同时也可以窥探作用域和闭包在 js 运行时中如何工作的。
前言
看案例之前,我们先回顾一下作用域和闭包的基础概念。
作用域: 简单来说就是决定了变量、函数和对象的可访问性。它定义了代码块中声明的标识符(如变量和函数)在何处可用。作用域一般分为:全局作用域、函数作用域、块级作用域、词法作用域和模块作用域
闭包: 就是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。简单来说,就是可以从内部函数访问外部函数的作用域的一种组合。
案例1:嵌套函数场景
我们来看有闭包场景的作用域链的访问过程。
在控制台上可以直接运行出结果就是 10
我们可以分析一下上面的的执行过程。
脚本准备阶段
在脚本执行前,js 解释器会收集函数的声明进行变量提升。所以此时 outsideFn 函数会被初始化在内存中。而 innerFn 函数由于是局部函数,所以并不会有变量提升。
执行阶段
- outsideFn 函数执行时会被推上调用栈中
- 在 outsideFn 函数内中
- innerVar 会被赋值为 10
- innerFn 函数被调用并推送到调用栈中
- 在 innerFn 函数内部
- console.log('innerVar', innerVar)执行的时候会根据作用域查找 innerVar 这个变量。
- 通过debug我们可以发现在函数作用域和全局作用域之间还存在一个闭包作用域
- 这个闭包就是 outsideFn 函数在创建的时候就会创建(从上面的图中可以看出闭包的标记,Closure (outsideFn) 看出这个闭包是 outsideFn 函数创建的),这是和函数声明的词法作用域有关,和函数调用位置无关。
作用域的访问方向按上图的箭头进行
案例2:独立函数场景
我们来看这个案例,我们来梳理一下作用域的访问过程。
在控制台我们可以看到输出的结果:
脚本准备阶段
同理,在执行前, foo 函数和 bar 函数会通过变量提升到脚本顶部并完成初始化。
执行阶段
- foo 会被调用并推送到调用栈中
- 在 foo 函数中
- x 变量 会从 undefined 变成 10
- bar 函数调用,并推送到 调用栈中。
- 在 bar 函数中
- console.log(x); 调用时,访问 x 变量,此时通过作用域链在 bar 函数作用域和全局作用域中找不到 x 变量。
- 所以最终就会报错 ReferenceError: x is not defined
小结
通过上述案例,我们可以总结作用域和闭包有以下特性:
- 作用域查找是从当前作用域进行向上查找直到全局作用域
- 作用域就是定义了变量、函数和对象的可访问范围
- 闭包在函数创建的时候就被同时创建了
- 闭包是一个函数和其周围的词法环境存在关联的一个组合。
- 和词法环境有关联才有闭包产生
- 和词法环境没有关联,就不会有闭包产生
如果对你有帮助的话,欢迎点赞、关注?、转发
- 上一篇: js中的闭包 js闭包的使用
- 下一篇: 前端几何计算GIS空间分析库介绍及优缺点分析
猜你喜欢
- 2025-06-23 JavaScript 开发者常犯的 10 个典型错误
- 2025-06-23 这7道问题可以检验你掌握Javascript的真正实力
- 2025-06-23 HarmonyOS NEXT 如何有效地进行内存管理和避免内存泄露?
- 2025-06-23 JS 函数柯里化(js函数柯里化面试题)
- 2025-06-23 《深入理解javascript原型和闭包系列》 知识点整理
- 2025-06-23 JS面试题突破:什么是闭包?(闭包 js)
- 2025-06-23 JavaScript闭包(javascript 闭包)
- 2025-06-23 “闭包到底是什么?90% 的前端开发者都没真正搞懂!”
- 2024-10-04 js中的闭包 js闭包的使用
- 2024-10-04 前端JS进阶系列-四-作用域链与闭包
你 发表评论:
欢迎- 最近发表
-
- Three.js vs Unity:工业可视化为何选择Web方案?
- 一款全新Redis UI可视化管理工具,支持WebUI和桌面——P3X Redis UI
- 时间线可视化实战:三款AI工具实测,手把手教你制作人生轨迹图
- 【推荐】一款可视化在线 Web 定时任务管理平台,支持秒级任务设置
- 重磅更新!FastDatasets 推出可视化 Web 界面
- 模具设计之UG钣金实例教程(3)_ug钣金基础教程
- 前端基于 RBAC 模型的权限管理实现
- 别再把JWT存在localStorage里了!2025年前端鉴权新思路
- 模具设计之曲面造型中不圆润的曲面如何处理技巧
- 9个专业级别的CSS技巧区分了解和精通的鸿沟
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- oracle面试 (55)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)