深入理解JS的执行上下文、词法作用域和闭包(下)

在这里插入图片描述

🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》

文章目录

  • 四、总结 🎯
    • 执行上下文、词法作用域和闭包的关系
    • 理解这些概念对编程的重要性 💪
    • 实际应用中的注意事项和最佳实践 👀
  • 参考资料

四、总结 🎯

执行上下文、词法作用域和闭包的关系

在JavaScript中,执行上下文、词法作用域和闭包之间存在一些复杂的关系。下面详细解释这些关系:

执行上下文:

执行上下文是JavaScript中变量、函数和对象等执行时的上下文环境。JavaScript中,执行上下文主要包括全局执行上下文(Global Execution Context)和函数执行上下文(Functional Execution Context)。

全局执行上下文包含全局作用域中的变量、函数和对象等。函数执行上下文则包含函数词法作用域中的变量、函数和对象等。

当执行一段代码时,首先会创建全局执行上下文,将全局变量、函数和对象等放入其中。然后,按照代码中的函数调用顺序,依次创建函数执行上下文,并将函数词法作用域中的变量、函数和对象等放入其中。

词法作用域:

词法作用域是由代码文本中变量声明的位置决定的。在JavaScript中,词法作用域主要包括函数词法作用域和块级作用域。

函数词法作用域是指函数可以访问其词法作用域中的变量,即使这个函数在其词法作用域之外执行。块级作用域是指使用letconst声明的变量具有块级作用域,只能在声明它们的代码块(如for循环、if语句等)内部访问。

词法作用域主要影响变量的查找和函数的调用。当需要在某个作用域中查找变量或调用函数时,JavaScript会按照词法作用域的规则,从当前作用域开始,向上级作用域逐层查找,直到找到为止。

闭包:

闭包(Closure)是JavaScript中一种重要的概念,它指的是一个函数可以访问其词法作用域中的变量,即使这个函数在其词法作用域之外执行。

闭包的主要特点包括函数可以记住并访问其词法作用域,即使这个作用域在函数执行完毕后被销毁。当一个函数在其词法作用域之外执行时,即使这个作用域在函数执行完毕后被销毁,该函数仍然可以访问其词法作用域中的变量。

总之,执行上下文、词法作用域和闭包之间的关系主要体现在以下几个方面:

  • 执行上下文是JavaScript中变量、函数和对象等执行时的上下文环境,词法作用域主要影响变量的查找和函数的调用。
  • 词法作用域是由代码文本中变量声明的位置决定的,闭包指的是一个函数可以访问其词法作用域中的变量,即使这个函数在其词法作用域之外执行。
  • 闭包可以让函数记住并访问其词法作用域,即使这个作用域在函数执行完毕后被销毁。

实际项目中,可以根据具体需求和场景,灵活地使用执行上下文、词法作用域和闭包等概念。

理解这些概念对编程的重要性 💪

理解执行上下文、词法作用域和闭包对编程的重要性主要体现在以下几个方面:

提高代码的可读性和可维护性:理解这些概念有助于更好地理解JavaScript中的变量作用域和函数调用等问题,从而提高代码的可读性和可维护性。

例如,理解词法作用域可以让我们更好地理解以下代码:

function foo() {let a = 1;function bar() {console.log(a); // 输出 1}bar();
}foo();

在这个例子中,bar函数在其词法作用域foo之外执行,但仍然可以访问foo作用域中的变量a。理解词法作用域有助于我们更好地理解这个例子。

避免变量污染和冲突:理解执行上下文和词法作用域可以帮助我们更好地管理变量的作用域,避免全局作用域和函数作用域中的变量冲突。

例如,以下代码会导致全局作用域和函数作用域中的变量冲突:

let a = 1;function foo() {let a = 2;console.log(a); // 输出 2
}foo();
console.log(a); // 输出 2

在这个例子中,全局作用域和函数作用域中的变量a冲突,导致输出结果不符合预期。理解执行上下文和词法作用域有助于我们避免这种错误。

实现模块化和封装:闭包可以让函数记住并访问其词法作用域,即使这个作用域在函数执行完毕后被销毁。这使得我们可以将一组相关的函数和变量封装在一个函数内部,然后返回这个函数的引用,这样就可以在其他地方调用这些函数并访问它们需要的变量。

例如,使用闭包实现一个简单的模块:

function createCart() {let products = [];function addProduct(product) {products.push(product);}function getProducts() {return products;}return {addProduct,getProducts};
}const cart = createCart();
cart.addProduct({ id: 1, name: 'Product 1' });
console.log(cart.getProducts()); // 输出:[{ id: 1, name: 'Product 1' }]

在这个例子中,createCart函数返回一个闭包,包含addProductgetProducts函数以及它们需要的变量products。这样可以实现模块化,将一组相关的函数和变量封装在一个函数内部。

总之,理解执行上下文、词法作用域和闭包对编程的重要性主要体现在提高代码的可读性和可维护性、避免变量污染和冲突以及实现模块化和封装等方面。实际项目中,可以根据具体需求和场景,灵活地使用这些概念。

实际应用中的注意事项和最佳实践 👀

在实际应用中,关于执行上下文、词法作用域和闭包,有一些注意事项和最佳实践:

使用letconst声明变量:在声明变量时,建议使用letconst而不是varletconst声明的变量具有块级作用域,可以在声明它们的代码块(如for循环、if语句等)内部访问,而var声明的变量具有函数作用域,可以在整个函数内部访问。

例如,以下代码使用let声明变量:

function foo() {let a = 1;function bar() {console.log(a); // 输出 1}bar();
}foo();

而以下代码使用var声明变量:

function foo() {var a = 1;function bar() {console.log(a); // 输出 1}bar();
}foo();

使用函数执行上下文:在实际项目中,可以使用函数执行上下文来封装一组相关的函数和变量,这样可以实现模块化和封装。

例如,以下代码使用函数执行上下文:

function createCart() {let products = [];function addProduct(product) {products.push(product);}function getProducts() {return products;}return {addProduct,getProducts};
}const cart = createCart();
cart.addProduct({ id: 1, name: 'Product 1' });
console.log(cart.getProducts()); // 输出:[{ id: 1, name: 'Product 1' }]

避免全局作用域污染:在实际项目中,避免全局作用域污染非常重要。全局作用域中的变量和函数可能会影响到其他代码,导致难以维护和调试。可以使用闭包来避免全局作用域污染。

例如,以下代码使用闭包避免全局作用域污染:

function createCounter() {let count = 0;return function() {count += 1;console.log(count); // 输出 1 2 3};
}const counter = createCounter();
counter();
counter();
counter();

总之,在实际应用中,关于执行上下文、词法作用域和闭包,需要注意使用letconst声明变量,使用函数执行上下文封装相关函数和变量,以及避免全局作用域污染。这些注意事项和最佳实践有助于提高代码的可读性和可维护性,降低代码的耦合度,使代码更加清晰和易于维护。

参考资料

[1]《JavaScript 高级程序设计》
[2] MDN Web Docs: JavaScript

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/700248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java程序设计】【C00262】基于Springboot的会员制医疗预约服务管理系统(有论文)

基于Springboot的会员制医疗预约服务管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的会员制医疗预约服务管理信息系统,本系统分为三种角色:管理员、医生和会员; 在系统…

JavaSec 基础之 XXE

文章目录 XMLReaderSAXReaderSAXBuilderDocumentBuilderUnmarshaller**SAXParserFactory**XMLReaderFactoryDigester总结 XMLReader public String XMLReader(RequestBody String content) {try {XMLReader xmlReader XMLReaderFactory.createXMLReader();// 修复&#xff1a…

如何让电脑待机而wifi不关的操作方法!!

1、一台电脑如果一天不关机,大约消耗0.3度电。 一般一台电脑的功耗约为250-400W(台式机)。 一台电脑每月的耗电量:如果是每小时300W每天10小时每月30天90KW,即90千瓦时的电。 这只是保守估计。 2、使用完毕后正常关闭…

企业微信应用开发:使用Cpolar域名配置进行本地接口回调的调试指南

文章目录 1. Windows安装Cpolar2. 创建Cpolar域名3. 创建企业微信应用4. 定义回调本地接口5. 回调和可信域名接口校验6. 设置固定Cpolar域名7. 使用固定域名校验 企业微信开发者在应用的开发测试阶段,应用服务通常是部署在开发环境,在有数据回调的开发场…

【MATLAB】 RLMD信号分解+FFT傅里叶频谱变换组合算法

有意向获取代码,请转文末观看代码获取方式~ 展示出图效果 1 RLMD分解算法 RLMD(Robust Local Mode Decomposition)是一种鲁棒的局部模态分解方法。它是通过在局部区间内对信号进行多项式拟合,提取局部特征,进而分解信…

【Java程序设计】【C00294】基于Springboot的车辆充电桩管理系统(有论文)

基于Springboot的车辆充电桩管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的车辆充电桩管理系统 本系统前台功能模块分为:首页功能和用户后台管理 后台功能模块分为:管理员功能和…

达梦数据库搭建和连接(详解一文看懂)

达梦数据库搭建和连接 一、数据库搭建1.安装前准备2.下载 Docker3.导入安装包4.启动docker版docker-compose版 5.启动/停止数据库 二、数据库连接1、下载DBeaver2、下载驱动3、DBeaver新建驱动数据库-驱动管理器新建驱动创建新驱动设置创建驱动-库驱动类确定和关闭 4、连接 博主…

回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测

回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测 目录 回归预测 | Matlab实现SSA-BiLSTM-Attention麻雀算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基…

[VulnHub靶机渗透] FourandSix2.01

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 …

stm32单片机的智能手环-心率-步数-距离-体温-蓝牙监控

一.硬件方案 随着社会的发展,人们的物质生活水平日渐提高,人们也越来越关注自己的健康。智能手环作为一种测量仪器,可以计算行走的步数和消耗的能量,所以人们可以定量的制定运动方案来健身,并根据运行情况来分析人体的…

7.(数据结构)堆

7.1 相关概念 堆(Heap)在计算机科学中是一种特殊的数据结构,它通常被实现为一个可以看作完全二叉树的数组对象。以下是一些关于堆的基本概念: 数据结构: 堆是一个优先队列的抽象数据类型实现,通过完全二叉树…

AI工具新革命:从ChatGPT到Sora,生成式AI改变世界

这个春节着实精彩,“春山学”吃透了,不如把目光移向OpenAI又一重磅产品——文生视频大模型Sora。智能新纪元已然开启,因为正如周鸿祎所说:“,Sora的诞生意味着AGI(通用人工智能)的实现将从10年缩短到1年。”…

.netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项

1、SqlSugarCore 相关 1.1 主项目添加数据&#xff0c;否则会报数据库连接错误&#xff1a; <InvariantGlobalization>false</InvariantGlobalization> <PropertyGroup><TargetFramework>net8.0</TargetFramework><Nullable>enable</…

二维码(CTF)misc

知识点&#xff1a;文件剥离zip密码爆破 用到了fcrackzip工具&#xff1a; -b :采用爆破的方式 -c :采用什么类型的密码&#xff0c;1 数字类型 a 小写字母 A 大写字母 ‘aA1’ 大小写字母数字混合等 -l :指定密码的位数 -u :过滤掉不正确的密码记录&#xff1b;只显示正…

C# winfroms使用socket客户端服务端代码详解

文章目录 1️⃣ 通信相关说明1.1服务端与客户端1.2 信息发送原理1.3 信息接收原理 2️⃣ socket代码2.1 客户端代码2.2 服务端代码 3️⃣ 定时任务处理报文3.1 Timers定时任务 优质资源分享 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_4315141…

滚雪球学Java(71):深入剖析Java中的ArrayBlockingQueue底层实现与源码分析

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

SpringMVC 学习(一)之 SpringMVC 介绍

目录 1 MVC 介绍 2 SpringMVC 介绍 2.1 SpringMVC 特点 2.2 SpringMVC 的核心组件 2.3 SpringMVC 执行流程 3 参考文档 1 MVC 介绍 MVC (Model View Controller) 是一种设计思想&#xff0c;它将应用程序分为三大组件&#xff1a;模型 (Model)、视图 (View)、控制器 (Con…

在openEuler中通过KVM可视化安装华为FusionCompute的VRM节点

一、说明 本文是华为FusionCompute云平台配置的延续&#xff0c;是在CNA&#xff08;ComputingNode Agent&#xff0c;计算节点代理&#xff09;主机安装配置完成后&#xff0c;详细安装VRM&#xff08;Virtual Resource Manager&#xff0c;虚拟资源管理器&#xff09;节点的…

「JavaSE」String类3:字符串常量池

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;快来卷Java啦 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 字符串常量池 &#x1f349;常量池&#x1f349;字符串常量池&#x1f349;intern 方法 &#x1f349;常量池 在Java程序中&…

微服务-Alibaba微服务nacos实战

1. Nacos配置中心 1.1 微服务为什么需要配置中心 在微服务架构中&#xff0c;当系统从一个单体应用&#xff0c;被拆分成分布式系统上一个个服务节点后&#xff0c;配置文件也必须跟着迁移&#xff08;分割&#xff09;&#xff0c;这样配置就分散了&#xff0c;不仅如此&…