JavaScript 进阶实战课
石川
JavaScript Patterns and Anti-Patterns 等开源项目创建者,O'Reilly 技术评审
15066 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
JavaScript 进阶实战课
15
15
1.0x
00:00/00:00
登录|注册

11|通过JS引擎的堆栈了解闭包原理

你好,我是石川。
在前面讲到编程模式的时候,我们就提到过闭包。
如果说一个函数“出生”的地方是作用域,从出生到被回收的“一生”是它的生命周期,那么闭包则可以突破这种空间和时间上的限制,那它是怎么做到这种突破的呢?
这节课,我们就从 JavaScript 编译原理以及其中的栈和堆的数据结构开始,来看看闭包的原理。

静态和动态作用域

我们先从作用域的空间概念来说。作用域可以分为静态作用域(static scope)和动态作用域(dynamic scope)。
静态作用域,取决于变量和函数在何处声明,这里你可以想象成它的“出生地”,并在它执行之前就已经确定了。所以静态作用域又被称为词法作用域(lexical scope),因为函数的“出生地”是在词法分析时“登记”的。
动态作用域则相反。动态作用域下,函数的作用域是在函数调用的时候才决定的。所以取决于在何处调用,这里你可以想象成它的“居住地”,这个是可以后天修改的。
我们所写的 JavaScript 代码,通常是通过前端浏览器编译后运行的,这个过程是先编译后执行。所以 JavaScript 代码的作用域是在编译过程中通过分析它在何处声明来确定的,属于静态(词法)作用域。
下面我们来看看函数的作用域在代码编译的阶段是如何定义的,以及它在执行阶段的生命周期。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

JavaScript闭包的原理和作用域生命周期是本文的重点。文章首先介绍了静态作用域和动态作用域的概念,以及JavaScript代码的作用域是在编译过程中通过分析来确定的。接着详细描述了作用域在代码编译阶段的定义过程,以及函数在执行阶段的生命周期。文章还解释了函数的生命周期和执行时变量查找的过程,强调了作用域的层级和封装的重要性。最后,介绍了立刻调用的函数表达(IIFE)的使用方法。通过本文,读者可以深入了解JavaScript闭包的原理,以及作用域和函数生命周期的相关知识。此外,还介绍了变量和函数提升的特点,以及ES6引入的块级作用域。总之,本文通过深入的技术讲解,帮助读者更好地理解JavaScript闭包的原理和相关概念。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《JavaScript 进阶实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(8)

  • 最新
  • 精选
  • 坤海
    老师,全局变量会存到闭包里吗?为什么在闭包里用全局变量会影响性能呢?

    作者回复: 全局变量是可以在闭包里引用的。闭包里引用全局变量会影响性能是因为全局变量在函数执行销毁后,不会随着函数销毁,还会存在。

    2022-10-15归属地:北京
    2
  • Nuvole Bianche
    这一讲和我之前看的极客时间中李兵老师的专栏《浏览器工作原理》冲突点有点大。在李老师的专栏,他说的是:函数体中的代码在解析阶段并不会解析编译,而是在函数调用时会对函数体中的代码进行解析编译,创建函数执行上下文,作用域和可执行代码,并压入到调用栈栈顶,而本讲中的流程图和原文讲 :”根据流程图中的红色虚线框部分所示,在词法分析后,JavaScript 引擎会在做语法分析的同时,更新全局作用域和创建局部作用域。“ 本文后面从时间角度看,给我的认知也是一样的:函数体中的执行上下文,变量环境,词法环境等在一开始就解析全局作用代码时就准备好了,只是在执行阶段再入栈而出栈而已。 希望专栏老师解答一下。
    2023-03-25归属地:上海
    2
  • 神佑小鹿
    闭包 在 JavaScript 中,根据词法作用域的规则,内部函数总是可以访问其外部函数中声明的变量,当通过调用一个外部函数返回一个内部函数后,即使该外部函数已经执行结束了,但是内部函数引用外部函数的变量依然保存在内存中,我们就把【这些变量的集合称为闭包】。 比如外部函数是 foo,那么这些变量的集合就称为 foo 函数的闭包。
    2023-03-15归属地:上海
  • 神佑小鹿
    老师问个问题: 函数是对象,所以它肯定在堆上了。 那你说的那个函数执行完销毁,是指的什么,是整个对象的销毁??
    2023-03-15归属地:上海
    1
  • 神佑小鹿
    function createCounter(){ let i=0; function increment(){ i++; } function getValue(){ return i; } return {increment,getValue} } const counter = createCounter(); 这里为啥要用 let 呢?? 我试了下不用 let 也是对的。
    2023-03-15归属地:上海
  • 穷精致
    所以应该怎么理解闭包呢?
    2023-02-03归属地:北京
    1
  • kingsley
    这一节理解难度++
    2022-11-24归属地:浙江
    1
  • 卡卡
    在函数式编程中,可以用闭包实现partial application
    2022-10-13归属地:江苏
收起评论
显示
设置
留言
8
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部