2.5k字带你构建JS执行上下文知识体系(二)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 本文字数2.5k字,请读者耐心看完,会有收获,先赞后看,养成习惯

变量环境创建

变量环境(VariableEnvironment对象)其实也是一种词法环境,它与上面的词法环境不同的是,其解析的是var声明变量,存储标识符与对应的引用,其创建过程发生的事情和词法环境差不多,但是关于初始值上有一些差别,如下:

如果我们使用var声明一个变量b那么会在变量环境创建的时候解析,存放在环境记录器中,但是其值为undefined

VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      b: undefined,
    }
    outer: <null>
  }
复制代码

完整结构

好了,我们现在能够将一个完整的上下文结构以伪代码形式表现出来

ExecutionContext = {
  ThisBinding = <this value>,
  LexicalEnvironment: {  
    EnvironmentRecord: {  
         Type: "Object",
         a: < uninitialized >,
    }  
    outer: <null>  
  },
   VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      b: undefined,
    }
    outer: <null>
  }
}
复制代码

上下文的创建基本就是这样,不知道掘友有没有理解,如果没有理解可以反复阅读思考(我参考官方文档和各种文章学习了一个礼拜才算对上下文比较透彻),如果理解到位,那么就可以开始学习上下文执行都发生了什么。

上下文执行🚶

上下文的创建是在脚本或函数执行前,而执行过程中会进行执行栈和负责相关的行为

执行栈

栈是一种先进后出数据结构,我们的上下文在执行过程正是存储在栈中,我们称作执行栈。

function fn_1 () {
    fn_2();
}
function fn_2() {}
fn_1();
复制代码

我拿上面的脚本来给大家描述这一过程,上面的脚本包含了三个上下文,分别是全局上下文,fn_1函数上下文,fn_2函数上下文

  • 脚本执行,创建全局上下文并推入栈底
  • fn_1()被触发,执行前创建fn_1函数上下文并推入栈,执行内部代码
  • fn_2()fn_1()执行中被触发,创建fn_2函数上下文并推入栈,此刻fn_2为栈顶,执行内部代码
  • fn_2()执行完毕,出栈
  • fn_1()执行完毕,出栈
  • 应用程序关闭,全局上下文出栈

赋值

在上下文的创建阶段,我们在词法环境内部的环境记录器存储了标识符,而在执行阶段,就会进行赋值,执行的伪代码如下

LexicalEnvironment: {  
    EnvironmentRecord: {  
         Type: "Object",
         a: "猪痞恶霸",
    }  
    outer: <null>  
  },
复制代码

销毁回收🗑️

在上下文弹出栈后不会立刻被销毁,想要了解销毁的内容可以查阅垃圾回收相关的知识,垃圾回收不是本文的重点。

带着知识看问题❔

通过上面我们已经大致掌握了执行上下文的原理,带着知识看问题,文章开头我提出了变量提升作用域问题,那么我们来一一解答。

变量提升问题

关于变量提升:使用var声明变量,在声明前调用为undefinedundefined就是我们熟悉的声明但未赋值,这种现象叫做变量提升,但是letconst禁止了这一行为,使用let所声明的变量一定需要在声明后使用。

console.log(bar_1) // undefined
console.log(bar) // Cannot access 'bar' before initialization
let bar = 2 
var bar_1 = 1
复制代码

那么letconst是如何阻止变量提升的呢?

我们回到上下文创建这个过程中,词法环境和变量环境在创建过程中会解析不同形式声明的变量,词法环境的创建会解析letconst声明的变量并存入环境记录器对象中,并标记其并没有初始化,而变量环境的创建会解析var声明的变量存入环境记录器对象中,其值为undefined,这就是为什么使用var声明的变量会发生变量提升并且打印值为undefined

作用域问题

为什么能访问上层作用域中的变量,不能访问下层作用域中的变量,那么我们就需要思考我们内部是以什么形式访问上层作用域的

还记得我们词法环境中的外部环境引用outer吗,作为词法环境的一个组成部分,可以访问父级上下文的词法环境,也就可以访问到上层作用域的成员,而词法环境中并没有内部环境引用的组成,所以无法对子级词法环境进行一个访问。

最后◀️

本文参考了javascript高级程序设计,译文其他相关作者的参考文章,经过一个星期的学习理解,耗费三天时间总结出这篇,如有一些相关问题或者看法,欢迎各位掘友大佬在评论区留言,我们一起学习交流!✌️

相关文章
|
1月前
|
中间件 API
Next.js 实战 (八):使用 Lodash 打包构建产生的“坑”?
这篇文章介绍了作者在使用Nextjs15进行项目开发时遇到的部署问题。在部署过程中,作者遇到了打包构建时的一系列报错,报错内容涉及动态代码评估在Edge运行时不被允许等问题。经过一天的尝试和调整,作者最终删除了lodash-es库,并将radash的部分源码复制到本地,解决了打包报错的问题。文章最后提供了项目的线上预览地址,并欢迎读者留言讨论更好的解决方案。
41 10
|
2月前
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
71 12
|
3月前
|
JavaScript NoSQL API
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发如同一座灯塔,指引着数据的海洋。本文将带你航行在Node.js的海域,探索如何从一张白纸到完成一个功能完备的RESTful API。我们将一起学习如何搭建开发环境、设计API结构、处理数据请求与响应,以及实现数据库交互。准备好了吗?启航吧!
|
3月前
|
JSON 缓存 JavaScript
深入浅出:使用Node.js构建RESTful API
在这个数字时代,API已成为软件开发的基石之一。本文旨在引导初学者通过Node.js和Express框架快速搭建一个功能完备的RESTful API。我们将从零开始,逐步深入,不仅涉及代码编写,还包括设计原则、最佳实践及调试技巧。无论你是初探后端开发,还是希望扩展你的技术栈,这篇文章都将是你的理想指南。
|
3月前
|
缓存 负载均衡 JavaScript
构建高效后端服务:Node.js与Express框架实践
在数字化时代的浪潮中,后端服务的重要性不言而喻。本文将通过深入浅出的方式介绍如何利用Node.js及其强大的Express框架来搭建一个高效的后端服务。我们将从零开始,逐步深入,不仅涉及基础的代码编写,更会探讨如何优化性能和处理高并发场景。无论你是后端新手还是希望提高现有技能的开发者,这篇文章都将为你提供宝贵的知识和启示。
|
3月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
88 5
|
3月前
|
JSON JavaScript 前端开发
使用JavaScript和Node.js构建简单的RESTful API
使用JavaScript和Node.js构建简单的RESTful API
|
3月前
JS+CSS3文章内容背景黑白切换源码
JS+CSS3文章内容背景黑白切换源码是一款基于JS+CSS3制作的简单网页文章文字内容背景颜色黑白切换效果。
34 0
|
3月前
|
JavaScript 前端开发
JavaScript中的原型 保姆级文章一文搞懂
本文详细解析了JavaScript中的原型概念,从构造函数、原型对象、`__proto__`属性、`constructor`属性到原型链,层层递进地解释了JavaScript如何通过原型实现继承机制。适合初学者深入理解JS面向对象编程的核心原理。
50 1
JavaScript中的原型 保姆级文章一文搞懂
|
6月前
|
JavaScript 前端开发
JS:一篇文章带你搞懂什么是异步
JS:一篇文章带你搞懂什么是异步

热门文章

最新文章

  • 1
    当面试官再问我JS闭包时,我能答出来的都在这里了。
    47
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 3
    Node.js 中实现多任务下载的并发控制策略
    34
  • 4
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    26
  • 5
    【JavaScript】深入理解 let、var 和 const
    49
  • 6
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    47
  • 7
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    57
  • 8
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    57
  • 9
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    72
  • 10
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    57