重学前端
程劭非(winter)
前手机淘宝前端负责人
104095 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 57 讲
开篇词+学习路线+架构图 (3讲)
重学前端
15
15
1.0x
00:00/00:00
登录|注册

JavaScript执行(二):闭包和执行上下文到底是怎么回事?

你好,我是 winter。
在上一课,我们了解了 JavaScript 执行中最粗粒度的任务:传给引擎执行的代码段。并且,我们还根据“由 JavaScript 引擎发起”还是“由宿主发起”,分成了宏观任务和微观任务,接下来我们继续去看一看更细的执行粒度。
一段 JavaScript 代码可能会包含函数调用的相关内容,从今天开始,我们就用两节课的时间来了解一下函数的执行。
我们今天要讲的知识在网上有不同的名字,比较常见的可能有:
闭包;
作用域链;
执行上下文;
this 值。
实际上,尽管它们是表示不同的意思的术语,所指向的几乎是同一部分知识,那就是函数执行过程相关的知识。我们可以简单看一下图。
看着也许会有点晕,别着急,我会和你共同理一下它们之间的关系。
当然,除了让你理解函数执行过程的知识,理清这些概念也非常重要。所以我们先来讲讲这个有点复杂的概念:闭包。

闭包

闭包翻译自英文单词 closure,这是个不太好翻译的词,在计算机领域,它就有三个完全不相同的意义:编译原理中,它是处理语法产生式的一个步骤;计算几何中,它表示包裹平面点集的凸多边形(翻译作凸包);而在编程语言领域,它表示一种函数。
闭包这个概念第一次出现在 1964 年的《The Computer Journal》上,由 P. J. Landin 在《The mechanical evaluation of expressions》一文中提出了 applicative expression 和 closure 的概念。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《重学前端》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(113)

  • 最新
  • 精选
  • 麦哲伦
    老师能解释下这个么? var b = 10; (function b(){ b = 20; console.log(b); // [Function: b] })();

    作者回复: 这个地方比较特殊,"具有名称的函数表达式"会在外层词法环境和它自己执行产生的词法环境之间产生一个词法环境,再把自己的名称和值当作变量塞进去,所以你这里的b = 20 并没有改变外面的b,而是试图改变一个只读的变量b。 这块知识有点偏,随便看看就好。

    12
    32
  • Geek_f51da4
    老师,闭包我是这样理解的,函数里边的函数,这样的理解对吗

    作者回复: 完全错了

    9
    7
  • 张祥儒
    winter大大,我觉得应该用global object,和active object 来解释这个闭包,作用域,执行器上下文。

    作者回复: 这是ES3里的解释法,现在已经解释不了很多语法了。

    2
    7
  • beilunyang
    闭包其实是一个绑定了执行环境的函数。 var foo = 'foo'; function printFoo() { console.log(foo); } printFoo(); 所以printFoo这个函数是一个闭包,对吗

    作者回复: 对,其实JS里任何函数都是闭包......

    3
  • 海绵薇薇
    老师您好,对于 --- JavaScript 中跟闭包对应的概念就是“函数” 这句话我还是理解不够。 说是闭包和执行上下文没关系,但是词法作用域,不就和执行上下文相关吗?用到的标识符在作用域链上,作用域链不是在执行上下文里吗?

    作者回复: 执行上下文是词法作用域的一种实现方式,但不是唯一的实现方式,你要彻底搞清楚这些概念的意思,不要混在一起理解。

    1
  • 陈斌
    我查看另一篇博客资料: 执行上下文同时包含变量环境组件(VariableEnvironment)和词法环境组件(LexicalEnvironment),这两个组件多数情况下都指向相同的词法环境(Lexical Environment)。 一般情况下一个执行上下文内的Variable Environment和Lexical Environment指向同一个词法环境,之所以要区分两个组件,主要是为了实现块级作用域的同时不影响var声明及函数声明。 和老师您如下介绍的是否有点冲突? lexical environment:词法环境,当获取变量或者 this 值时使用。 variable environment:变量环境,当声明变量时使用。 我觉得我看了上面的博客之后,理解不了您的意思了?

    作者回复: 这个概念在标准中有过版本变化,所以以最新标准为准。

    1
  • J
    小白有点懵逼,老师可以解答下几个问题吗 > var 把 b 声明到哪里; b 表示哪个变量; b 的原型是哪个对象; let 把 c 声明到哪里; this 指向哪个对象。 > var b = {} 这样一句对两个域产生了作用 ? 两个域是指哪两个 > 分析了一些执行上下文中所需要的信息,并从var、let、对象字面量等语法中,推导出了词法作用域、变量作用域、Realm的设计。 ? 执行上下文需要的信息是哪些 ? 在哪里推导了,两个作用域在哪里

    作者回复: 这不就是课程讲的内容么

  • 泡泡
    老师,已经读了十几篇了,感觉知识讲的太深,专业词汇较多,读起来比较生涩

    编辑回复: 你具体在哪里不懂呢,可以留言呀。

  • 追梦
    请问老师,这个例子,是如何得出“可以看到,在 Global function with 三个环境中,b 的值都不一样”这个结论的? var b; void function(){ var env = {b:1}; b = 1; console.log("In function b:", b); with(env) { var b = 1; console.log("In with b:", b); } }(); console.log("Global b:", b);

    作者回复: 这里写错了一个地方,我改一下

  • Geek_56013e
    老师您的专业知识太强了,文中包含很多专业术语,在介绍某专业术语时带上了其他专业术语,而这些带上的专业术语部分在网上搜也是解释不清,导致很多地方看不懂、看起来比较费劲、只能猜测大意。比如对于「realm」的描述,只提了中文意思是“国度”“领域”“范围”和“包含一组完整的内置对象,而且是复制关系”,看完文章后,在js领域还是不清楚具体「realm」是什么含义,只能大概猜测。希望老师后续文章如果解释某专业术语时带上的其他专业术语时,能以日常常见代码为例解释。
    3
    298
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部