问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

javascript中的作用域和执行上下文

发布网友 发布时间:2024-09-05 23:11

我来回答

1个回答

热心网友 时间:2024-10-04 17:33

前言

本文将采用尽量简洁清晰的语言来讲清楚javascript中的作用域和执行上下文,读完本文能够学习到一下知识点:

作用域分为词法作用域和动态作用域,javascript属于哪一种?

词法作用域也叫静态作用域,它和动态作用域有什么区别?

作用域实在哪个阶段确定的?它的作用是什么?

执行上下文分为哪几类?什么时候会创建执行上下文?

如何管理众多的执行上下文?

带着这些疑问,让我们开始本文的阅读吧!

作用域

作用域是指程序源代码中定义变量的区域。

它规定了查找变量的规则以及当前代码对变量的访问权限。

javascript的作用域是词法作用域,也叫静态作用域。

词法作用域和动态作用域

词法作用域的英文名称是$LexicalScope$,$Lexical$的意思就是词法。

为什么叫做词法作用域呢?因为该作用域规则是在编译器进行代码编译时确定的。

编译器在进行代码编译时主要有三个阶段:

词法分析(Tokenizing|Lexing)

语法分析生成抽象语法树(Parsing)

代码生成(CodeGeneration)

关于更多编译器原理参考AnatomyofaCompiler

?静态作用域:在代码编译阶段或者说函数定义时确定,javascript的作用域属于这一种。

?动态作用域:在函数调用时确定。

来看一个例子就能明白它们的区别了。

varname='William'functionbar(){console.log(name)}functionfoo(){varname='Jane'bar()}foo()//打印结果为'William'

解释:bar函数执行时,发现console.log(name),首先查找自己函数内部有没有name,发现没有,于是再根据书写位置查找上一层,发现name,于是就输出了William。

那么如果是动态作用域又会是怎样的呢?执行bar发现当前作用域没有name,于是到调用函数的上一层也就是foo里寻找,于是输出Jane。

执行上下文

学习javascript变量的时候,我们经常都会听到变量提升,那么变量提升发生在什么时候呢?别急,往下看。

javascript引擎在执行一段可执行代码(executablecode)时是一段一段执行的,而不是一行一行执行。看下面例子:

varbar=function(){console.log('bar1')}bar()//bar1varbar=function(){console.log('bar2')}bar()//bar2functionbar(){console.log('bar1');}bar()//bar2functionbar(){console.log('bar2');}bar()//bar2

可以看到,如果是代码是一行一行往下执行,那么第二个例子中第一个bar()结果应该是bar1,然而它却打印出了bar2。

那么javascript是如何把代码划分成段的呢?首先我们得清楚Javascript中的可执行代码有哪一些?

javascript中的可执行代码

分为三类:

全局代码

函数代码

eval代码

当执行遇到函数时,就会来划分一段代码,这里的一段具体来说就是我们所说的执行上下文,一个执行上下文的生命周期分为两个阶段:

创建阶段

执行阶段

在创建阶段会做很多的准备工作,包括变量提升,作用域链的确定,确定this指向等工作,具体的准备工作我们以后再说,这里先记住,执行上下文是在函数调用时创建的。

我们先弄清楚执行上下文是如何管理的。

执行上下文栈

对于一个源代码程序,没调用一个函数就会创建一个执行上下文,这些执行上下文统一使用一个执行上下文栈来管理,用一个例子来讲一下其运行机制:

functionfoo1(){varname='William'console.log(name)}functionfoo2(){foo1()}functionfoo3(){foo2()}foo3()

我们使用一个数组ContextStack来模拟栈,执行代码时最先遇到全局上下文globalContext,将其入栈

ContextStack=[globalContext]

然后代码往下执行,遇到函数调用foo3(),于是创建了一个foo3函数的执行上下文,将其入栈

ContextStack.push(<foo3>functionContext)/*ContextStack=[globalContext,<foo3>functionContext]*/

发现foo3还调用了foo2:

ContextStack.push(<foo2>functionContext)/*ContextStack=[globalContext,<foo3>functionContext<foo2>functionContext]*/

foo2居然还调用了foo1:

ContextStack.push(<foo1>functionContext)/*ContextStack=[globalContext,<foo3>functionContext<foo2>functionContext<foo1>functionContext]*/

foo1执行,打印William,执行完毕,将它的上下文出栈,其他函数紧接着执行完毕,依次出栈:

ContextStack.pop()ContextStack.pop()ContextStack.pop()/*ContextStack=[globalContext]*/

整个应用程序执行完毕时globalContext才会出栈,否则会一直作为栈底元素。

总结

总结部分就来简短回答一下前言中的问题:

1??作用域分为词法作用域和动态作用域,javascript属于哪一种?2??词法作用域也叫静态作用域,它和动态作用域有什么区别?3??作用域实在哪个阶段确定的?它的作用是什么?

javascript的作用域是词法作用域,它是在代码编译阶段时根据代码位置决定的,它的作用是规定了变量查找的规则和确定当前代码对变量的访问权限。

4??执行上下文分为哪几类?什么时候会创建执行上下文?如何管理众多的执行上下文?

执行上下文根据可执行代码的种类可以分为全局、函数、eval三类。在函数进行调用时会创建全局上下文。执行上下文栈用于管理执行上下文,当遇到函数调用时就生成一个对应的上下文并入栈,当函数执行完毕时就把对应的上下文出栈。除非整个程序执行完毕,否则全局上下文会一直待在栈底。

思考题

留个思考题,下面两段程序结果是什么?有什么不同吗?

试试用本文的知识使用栈模拟一下其过程!

varscope="globalscope";functioncheckscope(){varscope="localscope";functionf(){returnscope;}returnf();}checkscope();varbar=function(){console.log('bar1')}bar()//bar1varbar=function(){console.log('bar2')}bar()//bar20原文:https://juejin.cn/post/7095237284814929957
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
bwp是什么币别 boc是什么货币 bgn什么币 什么是博茨瓦纳普拉 EXCEL能用函数实现自动打分吗,就是那种去掉最低分和最高分后的总分... excel怎么自动计算比赛成绩 咸鱼怎么删除卖家的好评和评分 你怎么现在才吃饭呢???韩语翻译下 why don't you come and play with me什么意思 为什么不出去吃饭 翻译 javascript和web的关系(javaweb和javascript) 前端基石:面向对象的细节知识(较长) new关键字相关知识点总结 javascript进阶知识4-正则表达式 javascript要学什么? javascript有哪些方面的知识? 兽皮痣右胳膊小臂长有黑色毛发胎记,哪家医院治疗最专业?【兽皮痣... 沈丘县胎记医院脸上有一点五分硬币那么大手术费多少钱 祛除面部胎记多少钱 有首歌里面有一句(几千年礼仪之帮)叫什么名字? ...其中有两句歌词是:五千年礼仪之邦,泱泱我大中华,天是坤,地是... 描写泉水的好段? 唯物主义是什么意思呀 唯物主义的意思 黄柏煮水的功效与作用 黄柏的功效与作用是什么 吕继宏出版专辑 离婚判决之后还能再起诉吗? 两次起诉离婚没有判离还能起诉吗? 判决不准离婚之后还能起诉离婚吗 JavaScript数组操作必须熟练运用的10个方法 JavaScript之彻底理解原型与原型链 哈密瓜怎么去皮切块 哈密瓜怎么削皮 哈密瓜削皮方法 什么是肥厚型心肌病?可怕吗? 肥厚型心肌病临床上的特点 肥厚型心肌病的鉴别方法 肥厚型心肌病临床表现 肥厚型心肌病心脏彩超的表现 关于《琼明神女录》 底特律大都会国际机场简介 工作超十年被公司降职降薪,又唔出书面通知,只是收到口头通知,如何是好... ...口头通知降职降薪 然后公司又不出书面通告 这怎么办? 给老人送礼应该考虑哪些问题? 给老人送什么礼物比较好啊? 给80岁老人买礼物送什么好? 给老人送礼物送什么好? 朋友欠钱写了借条一直不还钱怎么起诉 保温杯总进虫子怎么办 我早上到办公室十有八九都发现保温杯里面有一个虫子进去,不知道从哪里...