JavaScript深入 执行上下文(五):整个过程
lipiwang 2024-10-16 13:10 45 浏览 0 评论
- JavaScript深入 执行上下文(一):作用域
- JavaScript深入 执行上下文(二):执行上下文栈
- JavaScript深入 执行上下文(三):变量对象
- JavaScript深入 执行上下文(四):作用域链
- JavaScript深入 执行上下文(五):整个过程
V8 执? JS 代码的流程
JavaScript属于解释型语?,JavaScript 的执?分为 「解析 」和 「执? 」两个阶段,如下:
解析阶段:
- 词法分析
- 语法分析
- 作?域规则确定(即:初始化各个函数[[scope]]属性的值)
执?阶段:
- 创建执?上下? context
- 执?函数代码
- 垃圾回收
注:作?域在解析阶段就确定,不会改变;?执?上下?,是在执?阶段才确定,可能发?改变。举个例?:
var a = 10;
function fn() {
var b = 20;
function bar() {
console.log(this.b); // 200
console.log(a + b); // 30
}
return bar;
}
var x = fn(),
b = 200;
x();
上?的打印的结果为 200、30,是因为对于 this.b 来说,this 的指向,就是执?上下?中确定的(即this指向当前执行环境);? bar 函数中的 b 值,是在 js解析阶段 bar 函数定义时,就已经明确 bar 函数的作?域链,为 bar -> fn -> 全局,所以 b 变量会沿着作?域链寻找,找到 fn 中的定义,值为 20
JS执?阶段的整个过程
现在加上this, 详细的介绍下js在执?阶段全程都发生了什么~
以下过程,往复进行:
1、准备执行时:创建执行上下文并压栈 => 初始化执行上下文
2、执行过程中: 改变活动对象中的属性值
以下面例子为例:
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
执行过程如下:
1、执行全局代码,创建全局执行上下文,全局上下文被压入执行上下文栈
ECStack = [
globalContext
];
2、全局上下文初始化(初始化全局环境的变量对象VO,确定全局环境的Scope,绑定全局环境的this)
globalContext = {
VO: {
global: window,
scope: undefined,
checkscope:reference to function checkscope
},
Scope: [globalContext.VO],
this: globalContext.VO
}
变量对象VO:
- 存储了在上下文中定义的变量和函数声明;除了我们无法访问外,和普通对象没什么区别
- 对于函数,执行前的初始化阶段叫变量对象,执行中就变成了活动对象
- 每一个执行环境都有一个与之相关的变量对象,其中存储着上下文中声明的:变量、函数、形式参数
3、发生在解析阶段: checkscope函数执行前,在解析阶段,checkscope函数被创建,保存全局环境的作用域链,到函数checkscope的内部属性[[scope]]中
checkscope.[[scope]] = [
globalContext.VO
];
4、执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 函数执行上下文被压入执行上下文栈
ECStack = [
checkscopeContext,
globalContext
];
5、初始化 checkscope 函数执行上下文,会有以下几步:
① ? arguments 创建活动对象 checkscopeContext.AO(活动对象初始化:形参 > 函数声明 > 变量声明)
② 利?checkscopeContext.AO 与 checkscope.[[scope]],形成checkscope 函数执?环境的作?域链 checkscopeContext.Scope
③ 绑定 this 到 undefined(?严格模式下会绑定到全局对象)
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope: undefined,
f: reference to function f(){}
},
Scope: [AO, globalContext.VO],
this: undefined
}
活动对象 AO:
- 在没有执?当前环境之前,变量对象中的属性都不能访问。但是进?执?阶段之后,变量对象转变为了活动对象,所以活动对象和变量对象其实是?个东?,只是处于 执?环境的不同?命周期
- AO 实际上是包含了 VO 的。因为除了 VO 之外,AO 还包含函数的参数 parameters,以及 arguments 这个特殊对象
6、发生在解析阶段: f 函数执?前,在解析阶段。 更新 f.[[scope]], checkscopeContext.AO.scope 等赋值
f.[[scope]] = [
checkscopeContext.AO,
globalContext.VO
];
checkscopeContext = {
AO: {
arguments: {
length: 0
},
Scope: "local scope",
f: reference to function f(){}
},
Scope: [AO, globalContext.VO],
this: undefined
}
7、执行f函数, 创建 f 函数执行上下文,f 函数执行上下文被压入执行上下文栈
ECStack = [
fContext,
checkscopeContext,
globalContext
];
8、f 函数执行环境初始化, 跟第 5 步相同:
① ? arguments 创建活动对象 fContext.AO(活动对象初始化:形参 > 函数声明 > 变量声明)
② 利? fContext.AO 与 f.[[scope]],形成f函数执?环境的作?域链 fContext.Scope
③ 绑定 this 到 undefined(?严格模式下会绑定到全局对象)
fContext = {
AO: {
arguments: {
length: 0
}
},
Scope: [AO, checkscopeContext.AO, globalContext.VO],
this: undefined
}
9、f 函数中代码执?。对 scope 进?查找。查找从作?域链中当前活动对象,开始沿着作?域链向上查找 // 查找过程: 1. fContext.AO.scope 没有该变量声明,继续 2. checkscopeContext.AO.scope 有该变量声明,获取其值为"local scope"
10、f 函数执行完毕,f 函数上下文从执行上下文栈中弹出
ECStack = [
checkscopeContext,
globalContext
];
11、 checkscope 函数在执?完 f 处,获取 f 执?的返回值 "local scope",函数继续向下执?。 checkscope 函数执行完毕,checkscope 执行上下文从执行上下文栈中弹出
ECStack = [
globalContext
];
12、 代码执?流回到全局执?环境中调? checoscope 处,拿到 checkScope 返回值并继续向下执? 13、 直到程序终?,或者??关闭。全局上下?出栈并销毁
相关推荐
- 一个简单便捷搭建个人知识库的开源项目(MDwiki)
-
这里我通过自动翻译软件,搬运总结MDwiki官网的部署和使用方法。第一步:下载编译好的后MDwiki文件,只有一个HTML文件“mdwiki.html”。第二步:在mdwiki.html同级目录创建“...
- 强大、简洁、快速、持续更新 PandaWiki新一代 AI 驱动的开源知识库
-
PandaWiki是什么PandaWiki是一款AI大模型驱动的开源知识库搭建系统,帮助你快速构建智能化的产品文档、技术文档、FAQ、博客系统,借助大模型的力量为你提供AI创作、AI问答...
- DeepWiki-Open: 开源版Deepwiki,可自己构建github文档库
-
Deepwiki是Devin团队开发的github文档库,用户能免费使用,但代码不是开源,而DeepWiki-Open侧是开源版本的实现。DeepWiki-Open旨在为GitHub和GitLa...
- 最近爆火的wiki知识管理开源项目PandaWiki
-
项目介绍PandaWiki是一款AI大模型驱动的开源知识库搭建系统,帮助你快速构建智能化的产品文档、技术文档、FAQ、博客系统,借助大模型的力量为你提供AI创作、AI问答、AI搜索等...
- 轻量级开源wiki系统介绍(轻量开源论坛系统)
-
wiki系统有很多DokuWiki、MediaWiki、MinDoc等等都是开源的wiki系统。商业版的wiki,像很多企业在用的confluence等。今天我们讲的是一款轻量级且开源的文档管理系统:...
- DNS解析错误要怎么处理(dns解析状态异常怎么办)
-
在互联网时代,网络已经成为人们生活和工作中不可或缺的一部分。然而,当遇到DNS解析错误时,原本畅通无阻的网络访问会突然陷入困境,让人感到十分困扰。DNS,即域名系统,它如同互联网的电话簿,将人们易于...
- 网页加载慢?这些方法让你秒开网页!
-
打开浏览器,信心满满地准备查资料、看视频或者追剧,却发现网页怎么都打不开!是不是瞬间感觉手足无措?别慌,这个问题其实挺常见,而且解决起来并没有你想象的那么复杂。今天就来聊聊网页打不开究竟是怎么回事,以...
- windows11 常用CMD命令大全(windows11msdn)
-
Windows11中的命令提示符(CMD)是一个强大的工具,可以通过命令行执行各种系统操作和管理任务。以下是一些常用的CMD命令,按功能分类整理,供你参考:一、系统信息与状态systeminfo显...
- 电脑提示DNS服务器未响应怎么解决?
-
我们在使用电脑的时候经常会遇到各种各样的网络问题,例如最近就有Win11电脑用户在使用的时候遇到了DNS未响应的问题,遇到这种情况我们应该怎么解决呢? 方法一:刷新DNS缓存 1、打开运行(W...
- 宽带拨号错误 651 全解析:故障定位与修复方案
-
在使用PPPoE拨号连接互联网时,错误651提示「调制解调器或其他连接设备报告错误」,通常表明从用户终端到运营商机房的链路中存在异常。以下从硬件、系统、网络三层维度展开排查:一、故障成因分类图...
- 如何正确清除 DNS 缓存吗?(解决你访问延时 )
-
DNS缓存是一个临时数据库,用于存储有关以前的DNS查找的信息。换句话说,每当你访问网站时,你的操作系统和网络浏览器都会保留该域和相应IP地址的记录。这消除了对远程DNS服务器重复查询的...
- 网络配置命令:ipconfig和ifconfig,两者有啥区别?
-
在计算机网络的世界里,网络接口就像是连接你电脑和外部网络的桥梁,而网络配置则是确保这座桥梁稳固、通信顺畅的关键。提到网络配置工具,ipconfig和ifconfig绝对是两个绕不开的名字。它们一...
- 救急的命令 你会几个?(救急一下)
-
很多人都说小编是注册表狂魔,其实不完全是,小编常用的命令行才是重点。其实所谓的命令行都是当初DOS时代的标准操作方式,随着Windows不断演化,DOS的命令早已成为Windows的一部分了——开始菜...
- 电脑有网却访问不了GitHub原来是这样
-
当满心欢喜打开电脑,准备在GitHub这个“开源宝藏库”里挖掘点超酷的项目,却遭遇了网页无法访问的尴尬。看着屏幕上那令人无奈的提示,原本高涨的热情瞬间被泼了一盆冷水,是不是感觉世界都不美好了...
- rockstargames更新慢| r星更新速度 怎么办 解决办法
-
rockstargames更新慢|r星更新速度怎么办解决办法说到RockstarGames,那可是游戏界的大佬,作品个顶个的经典。但话说回来,每当新内容更新时,那蜗牛般的下载速度,真是让人急得...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- maven镜像 (69)
- undefined reference to (60)
- zip格式 (63)
- oracle over (62)
- date_format函数用法 (67)
- 在线代理服务器 (60)
- shell 字符串比较 (74)
- x509证书 (61)
- localhost (65)
- java.awt.headless (66)
- syn_sent (64)
- settings.xml (59)
- 弹出窗口 (56)
- applicationcontextaware (72)
- my.cnf (73)
- httpsession (62)
- pkcs7 (62)
- session cookie (63)
- java 生成uuid (58)
- could not initialize class (58)
- beanpropertyrowmapper (58)
- word空格下划线不显示 (73)
- jar文件 (60)
- jsp内置对象 (58)
- makefile编写规则 (58)