简单理解闭包|作用域和作用域链|执行上下文

本文主要介绍对闭包|作用域和作用域链|执行上下文三个的理解。

1.闭包

(1)定义

闭包指有权访问另一个函数作用域中变量的函数。

(2)闭包的基本特性

函数嵌套内部函数可以访问外部函数的作用域,包括参数和局部变量,即使外部函数已经执行完毕。

持久性闭包的生命周期比其外部函数的生命周期更长。只要闭包存在,就可以继续访问和操作其外部函数的变量。

(3)闭包的用途

数据封装和隐私:通过闭包,可以隐藏函数的具体实现和状态,只对外提供公共的接口函数。这有助于实现数据封装和隐藏内部实现细节。

回调函数和异步编程:在JavaScript等语言中,闭包常用于处理回调函数,帮助异步编程中维持上下文(即变量作用域)的连续性。

模拟私有变量:在JavaScript等没有原生私有变量概念的语言中,闭包可以用来模拟私有变量和私有方法。

示例:

function createCounter() { let count = 0; // 外部函数的局部变量 return function() { // 内部函数,闭包 count += 1; return count; } 
} const counter = createCounter(); 
console.log(counter()); // 输出: 1 
console.log(counter()); // 输出: 2 
......
// 注意:createCounter函数已经执行完毕,内部变量count仍可以被counter函数访问和修改

在这个例子中,createCounter 函数创建了一个局部变量 count,并返回了一个内部函数。这个内部函数就是一个闭包,因为它可以访问和修改其外部函数 createCounter 的局部变量 count。当 createCounter 函数已经执行完毕,count 变量仍然被保存在内存中,具有持久性。

2.作用域和作用域链

(1)作用域(Scope)

作用域定义了变量和函数在代码中的可访问性。简单来说,它决定了在哪里可以访问到特定的变量或函数。在JavaScript中,主要有两种作用域:全局作用域和局部作用域(也称为函数作用域,ES6后引入了块级作用域,如letconst声明的变量)。let/const/var的区别及理解

  • 全局作用域:在代码的任何地方都可以访问到的变量和函数拥有全局作用域。在浏览器环境中,全局作用域是window对象,而在Node.js中,全局作用域是global对象。

注意:全局作用域缺点就是过多使用全局作用域变量会污染全局命名空间,容易造成命名冲突。

  • 局部作用域:在函数或代码块(ES6+)内部声明的变量或函数只能在其声明的函数或代码块内部访问。

除了全局作用域和局部作用域,还有块级作用域。块级作用域指的是变量或常量在代码块(如大括号{}包围的区域)内部定义后,其作用范围仅限于该代码块内部。

(2)作用域链(Scope Chain)

作用域链是JavaScript在查找变量时的一个过程或机制。当JavaScript需要访问一个变量时,它会从当前作用域开始查找该变量。如果当前作用域中没有找到该变量,它就会依次向上级作用域查找,直到全局作用域window对象。这个逐级查找的过程就形成了作用域链。

作用域链的作用:保证对执行环境有权访问的所有变量和函数的有序访问,通过作用域链可以访问到外层的变量和函数。

示例

var x = 'global'; 
function outer() { var y = 'outer'; function inner() { var z = 'inner'; console.log(x); // 查找顺序:inner -> outer -> global,找到 'global' console.log(y); // 查找顺序:inner -> outer,找到 'outer' console.log(z); // 查找顺序:inner,找到'inner'}inner(); console.log(z); // z is not defined//访问z变量在outer作用域中,会报错,因为z只在inner作用域中 
} 
outer();

在这个例子中,inner函数的作用域链包括inner自身的作用域、outer函数的作用域以及全局作用域。当inner函数内部尝试访问变量x时,由于innerouter作用域中都没有x变量,所以会继续在全局作用域中查找,成功找到x的值为'global'

3.执行上下文

(1) 定义

执行上下文是指函数调用时在执行栈中产生的当前函数(或全局对象,如浏览器中的window)的执行环境。这个环境像是一个隔绝外部的容器,保管着可访问的变量、this对象等。

JavaScript中任何代码都是在执行上下文中运行的。执行上下文为代码的执行提供了必要的环境和信息。

(2)生命周期

执行上下文的生命周期可以分为三个阶段

创建阶段:在这个阶段,JavaScript引擎会进行词法分析、语法分析,确定作用域规则,并创建变量对象。对于全局执行上下文,变量对象就是全局对象(如window);对于函数执行上下文,变量对象包括函数参数、内部变量和函数声明等。同时,建立作用域链,确定this的指向。

执行阶段:在这个阶段,JavaScript引擎会逐行执行代码,进行变量赋值、函数调用等操作。执行上下文会根据词法环境和变量环境来执行代码,维护执行过程中的状态,如变量的值和执行的位置。如果遇到函数调用,会创建新的函数执行上下文,并将其压入执行栈的顶部。当函数执行完毕后,相应的执行上下文会从执行栈中弹出,控制权交给当前的栈顶执行上下文。

销毁阶段:当执行上下文执行完毕后,它会被销毁,并释放相关的资源。

(3)执行上下文栈

定义:执行上下文栈是一种用于管理执行上下文的数据结构,它遵循后进先出的原则。每当JavaScript引擎开始执行一段代码时,就会创建一个新的执行上下文,并将其压入执行栈中。当前正在执行的代码始终位于栈顶,执行完毕后会弹出栈顶的执行上下文。

作用:执行上下文栈确保了代码的执行顺序和上下文环境的正确管理。它允许JavaScript引擎在多个执行上下文之间切换,并在适当的时候销毁不再需要的执行上下文。

(4) 执行上下文的类型

JavaScript中有三种执行上下文:

全局执行上下文:任何不在函数内部的都是全局执行上下文,当JavaScript程序开始运行时创建的第一个执行上下文创建一个全局的window对象,设置this的值等于这个全局对象。

函数执行上下文:在调用函数时创建的执行上下文,它代表函数的作用域,而this的值取决于函数的调用方式。

Eval函数执行上下文:不常用。

简单来说,执行上下文是在执行JavaScript代码前,先解析代码。解析时先创建全局执行上下文环境,把代码中即将执行的变量和函数声明都拿出来,变量先赋值为undefined,函数先声明好。完成后,才开始正式的执行程序。在一个函数执行之前也会创建一个函数执行上下文环境,不过函数执行上下文会多this、arguments、函数的参数。

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

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

相关文章

免费【2024】springboot 基于微信小程序的宠物服务中心

博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

JavaDS —— 二叉搜索树、哈希表、Map 与 Set

前言 我们将学习 Map 与 Set 这两个接口下的 TreeMap 与 TreeSet ,HashMap 与 HashSet ,在学习这四个类使用之前,我们需要先学习 二叉搜索树与 哈希表的知识。 二叉搜索树 在学习二叉树的时候,我们就已经了解过二叉搜索树的概念…

酒店智能门锁接口pro[0922]D801 对接收银-SAAS本地化-未来之窗行业应用跨平台架构

proUSB接口函数[0922中性版]-D801 调用函数库: 提供Windows下的32位动态连接库proRFL.DLL,函数使用详细说明 //-----------------------------------------------------------------------------------// 功能:读DLL版本,不涉…

【Linux C | 网络编程】进程池退出的实现详解(五)

上一篇中讲解了在进程池文件传输的过程如何实现零拷贝,具体的方法包括使用mmap,sendfile,splice等等。 【Linux C | 网络编程】进程池零拷贝传输的实现详解(四) 这篇内容主要讲解进程池如何退出。 1.进程池的简单退…

Java并发编程(上)

并发:多个线程(进程)竞争一个资源 并行:多个线程(进程)同时运行不同资源 线程和进程的关系简单地说,进程是一个容器,一个进程中可以容纳若干个线程,一个进程里面&#…

微信小程序入门

创建一个入门程序 这是index.vxml代码 <!--index.wxml--> <navigation-bar title"Weixin" back"{{false}}" color"black" background"#FFF"></navigation-bar> <view class"container" ><view&…

苹果CMS:资源采集站如何设置定时采集详细教程讲解

我们搭建好站点之后&#xff0c;会自定义一些采集&#xff0c;但是需要每天去手动执行&#xff0c;有时候甚至会忘记&#xff0c;那我们如何处理呢&#xff1f;今天我们就来介绍一下如何设置定时器。 如果按照官方例子来设置定时器会遇到一个问题就是采集的资源未绑定类型&…

WAF+API安全代表厂商|瑞数信息入选IDC报告《生成式AI推动下的中国网络安全硬件市场现状及技术发展趋势》

近日&#xff0c;全球领先的权威资讯机构IDC正式发布《IDC Market Presentation&#xff1a;生成式AI推动下的中国网络安全硬件市场现状及技术发展趋势&#xff0c;2024》报告。报告中IDC 评估了众多厂商的安全硬件产品能力&#xff0c;并给出了产品对应的推荐厂商供最终用户参…

04 | 深入浅出索引(上)

此系列文章为极客时间课程《MySQL 实战 45 讲》的学习笔记&#xff01; 索引的常见模型 可以提供查询效率的数据结构有很多&#xff0c;常见的有三种&#xff1a;哈希表、有序数组、搜索数。 哈希表是一种以 key-value 形式存储的数据结构。输入一个 key&#xff0c;通过固定…

强烈推荐java人,2024年大厂面试背这份(八股文+场景题结合)!很管用!

2024 年的行情&#xff0c;和 3~4 年前不同&#xff0c;通过海量简历投递和海量面试找工作的时代已经过去了。 在如今面试机会较少&#xff0c;并且面试难度较大的情况下。 充分做好面试的准备才是快速通过面试最有效的方法&#xff01; 切忌把真实面试当靶场&#xff0c;最…

信息学奥赛初赛天天练-48-CSP-J2020完善程序2-变量交换、冒泡排序、贪心算法、最小区间覆盖

PDF文档公众号回复关键字:20240728 2020 CSP-J 完善程序2 1 完善程序 (单选题 &#xff0c;每小题3分&#xff0c;共30分) 最小区间覆盖 给出 n 个区间&#xff0c;第 i 个区间的左右端点是 [ai,bi]。现在要在这些区间中选出若干个&#xff0c;使得区间 [0, m] 被所选区间的…

前端框架 element-plus 发布 2.7.8

更新日志 功能 组件 [级联选择器 (cascader)] 添加持久化属性以提升性能 (#17526 by 0song)[日期选择器 (date-picker)] 类型添加月份参数 (#17342 by Panzer-Jack)[级联选择器 (cascader)] 添加标签效果属性 (#17443 by ntnyq)[加载 (loading)] 补充加载属性 (#17174 by zhixi…

第九讲 后端1

后端&#xff08;Backend&#xff09; 用带噪声的数据估计内在状态&#xff08;Estimated the inner state from noisy data&#xff09;——状态估计问题渐进式&#xff08;Incremental&#xff09;&#xff1a;保持当前状态的估计&#xff0c;在假如新信息时&#xff0c;更新…

【算法专题】双指针算法之18. 四数之和(力扣)

欢迎来到 CILMY23的博客 &#x1f3c6;本篇主题为&#xff1a;双指针算法之18. 四数之和&#xff08;力扣&#xff09; &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算…

ProxmoxPVE虚拟化平台--U盘挂载、硬盘直通

界面说明 ### 网络设置 ISO镜像文件 虚拟机中使用到的磁盘 挂载USB设备 这个操作比较简单&#xff0c;不涉及命令 选中需要到的虚拟机&#xff0c;然后选择&#xff1a; 添加->USB设置选择使用USB端口&#xff1a;选择对应的U盘即可 硬盘直通 通常情况下我们需要将原有…

【Linux 16】进程间通信的方式 - 共享内存

文章目录 &#x1f308; 一、共享内存概述⭐ 1. 什么是共享内存⭐ 2. 如何实现共享内存⭐ 3. 操作系统允许存在多个共享内存⭐ 4. 操作系统如何管理共享内存⭐ 5. 获取共享内存的唯一标识符 key⭐ 6. 为什么要由用户提供 key &#x1f308; 二、查看共享内存⭐ 1. 使用 ipcs -m…

TCP 协议的 time_wait 超时时间

优质博文&#xff1a;IT-BLOG-CN 灵感来源 Time_Wait 产生的时机 TCP四次挥手的流程 如上所知&#xff1a;客户端在收到服务端第三次FIN挥手后&#xff0c;就会进入TIME_WAIT状态&#xff0c;开启时长为2MSL的定时器。 【1】MSL是Maximum Segment Lifetime报文最大生存时间…

root 用户和权限

目录 1. 超级管理员 root 2. 切换用户 Switch User 2.1 普通用户切换到 root 用户 2.2 root 用户切换到普通用户 3. sudo 命令 3.1 配置认证 无论是 Windows&#xff0c;MacOS&#xff0c;Linux 均采用多用户的管理模式管理权限&#xff1b; 1. 超级管理员 root 在 Li…

2年社招冲击字节,一天三面斩获offer

在工作满两年的时间选择了求变&#xff0c;带着运气和实力以社招身份重新看今天的互联网环境&#xff0c;从结果看还是复合预期的。 整个面试的流程还挺快的。周中让招聘专员给投递了简历。问什么时候面试&#xff0c;申请了一个周日&#xff0c;直接安排三面。下周周中就开启…

C#中的wpf基础

在WPF中&#xff0c;Grid 是一种非常强大的布局控件&#xff0c;用于创建网格布局。它允许你将界面划分为行和列&#xff0c;并将控件放置在这些行和列中。 以下是一些关键点和示例&#xff0c;帮助你理解 WPF 中的 Grid&#xff1a; 基本属性 RowDefinitions&#xff1a;定义…