04_闭包 (JS高级)

目录

 

一、闭包是什么

二、常见的闭包

三、闭包的作用

 四、闭包的生命周期

五、闭包的应用

5.1、定义JS模块方式一

5.2、定义JS模块方式二

六、闭包的缺点及解决

 七、经典习题


 

一、闭包是什么

闭包(closure)是一个嵌套的内部函数以及它所引用环境的组合。

创建闭包的常见方式是在一个函数内部创建另一个函数,而该内部函数可以访问外部函数的局部变量,当外部函数执行完毕后,通常会释放其局部变量,但闭包可以防止这种情况发生,闭包中的局部变量会继续存在,因为闭包会引用这些变量。

二、常见的闭包

// 1、下面是一个使用JavaScript创建闭包的例子:
function createCounter() {let count = 0;return function() {count++;return count;};
}const counter = createCounter();
console.log(counter()); // 输出: 1
console.log(counter()); // 输出: 2
console.log(counter()); // 输出: 3
  // 2. 将函数作为实参传递给另一个函数调用function showDelay(msg, time) {setTimeout(function () {alert(msg)}, time)}showDelay('atguigu', 2000)

三、闭包的作用

1. 使函数内部的变量在函数执行完后, 仍然存活在内存中(延长了局部变量的生命周期)

2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)

引发的问题:

1. 函数执行完后, 函数内部声明的局部变量是否还存在? 一般是不存在, 存在于闭包的变量才可能存在

2. 在函数外部能直接访问函数内部的局部变量吗? 不能, 但我们可以通过闭包让外部操作它

  function fn1() {var a = 2function fn2() {a++console.log(a)// return a}function fn3() {a--console.log(a)}return fn3}var f = fn1()f() // 1f() // 0

 四、闭包的生命周期

1. 产生: 在嵌套内部函数定义执行完时就产生了(不是在调用,如果是function定义的函数在预处理时就已经产生闭包,如果是变量赋值的形式定义function则是在执行到当前语句时)

2. 死亡: 在嵌套的内部函数成为垃圾对象时(即赋值为null)

  function fn1() {//此时闭包就已经产生了(函数提升, 内部函数对象已经创建了)var a = 2// 下面函数是通过函数定义的形式定义函数,即通过function定义函数,// 函数提升了,在函数执行前创建执行上下文的时候闭包就已经产生了function fn2 () {a++console.log(a)}return fn2}var f = fn1()f() // 3f() // 4f = null //闭包死亡(包含闭包的函数对象成为垃圾对象)

五、闭包的应用

5.1、定义JS模块方式一

* 具有特定功能的js文件

* 将所有的数据和功能都封装在一个函数内部(私有的)

* 只向外暴露n个方法的对象或函数

* 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能

myModule.js 

function myModule() {//私有数据var msg = 'My atguigu'//操作数据的函数function doSomething() {console.log('doSomething() '+msg.toUpperCase())}function doOtherthing () {console.log('doOtherthing() '+msg.toLowerCase())}//向外暴露对象(给外部使用的方法)return {doSomething: doSomething,doOtherthing: doOtherthing}
}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>闭包的应用_自定义JS模块</title>
</head>
<body>
<script type="text/javascript" src="myModule.js"></script><script type="text/javascript">var module = myModule()module.doSomething()module.doOtherthing()</script>
</body>
</html>

5.2、定义JS模块方式二

* 具有特定功能的js文件

* 将所有的数据和功能都封装在一个函数内部(私有的)

* 只向外暴露一个包信n个方法的对象或函数

* 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能

myModule2.js

(function () {//私有数据var msg = 'My atguigu'//操作数据的函数function doSomething() {console.log('doSomething() '+msg.toUpperCase())}function doOtherthing () {console.log('doOtherthing() '+msg.toLowerCase())}//向外暴露对象(给外部使用的方法)window.myModule2 = {doSomething: doSomething,doOtherthing: doOtherthing}
})()
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>闭包的应用_自定义JS模块2</title>
</head>
<body><script type="text/javascript" src="myModule2.js"></script>
<script type="text/javascript">myModule2.doSomething()myModule2.doOtherthing()
</script>
</body>
</html>

六、闭包的缺点及解决

1. 缺点

* 函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长

* 容易造成内存泄露

2. 解决

* 能不用闭包就不用

* 及时释放

  function fn1() {var arr = new Array[100000]function fn2() {console.log(arr.length)}return fn2}var f = fn1()f()f = null //让内部函数成为垃圾对象-->回收闭包

 七、经典习题

 //代码片段一var name = "The Window";var object = {name : "My Object",getNameFunc : function(){return function(){return this.name;};}};alert(object.getNameFunc()());  //  the window// object.getNameFunc() 返回了一个一个函数function,再执行通过(),此时是this是window//代码片段二var name2 = "The Window";var object2 = {name2 : "My Object",getNameFunc : function(){var that = this; // 此时this是指调用者object2return function(){return that.name2; // 会在object2中寻找name2};}};alert(object2.getNameFunc()()); //  my object

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

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

相关文章

网络模型-单臂路由配置相关命令

一、单臂路由配置相关命令 执行命令system-view&#xff0c;进入系统视图. 执行命令interface interface-type interface-number&#xff0c;进入接口视图, 执行命令port link-type {hybrid |trunk}&#xff0c;配置端口类型。 执行命令quit&#xff0c;退出接口视图。 执…

游戏行业 2024 Q1报告 | 国内同比上升7.6%,海外收入同比环比双增长,码住!

作为中国音像与数字出版协会主管的中国游戏产业研究院的战略合作伙伴&#xff0c;伽马数据发布了《2024年1—3月中国游戏产业季度报告》。 数据显示&#xff0c; 2024年1—3月&#xff0c;中国游戏市场实际销售收入726.38亿元&#xff0c;同比增长7.60%&#xff0c;主要受移动游…

Python面试宝典:Python中与异步编程和协程相关的面试笔试题(1000加面试笔试题助你轻松捕获大厂Offer)

Python面试宝典:1000加python面试题助你轻松捕获大厂Offer【第二部分:Python高级特性:第十三章:并发编程:第三节:异步编程和协程】 第十三章:并发编程第三节:异步编程和协程异步编程和协程相关的知识异步编程基础异步函数(async function)等待协程(awaiting a corou…

信息系统项目管理师--八大绩效域-项目工作绩效域

信息系统项目管理师的八大绩效域包括&#xff1a;干系人、团队、开发方法和生命周期、规划、项目工作、交付、不确定性、度量。 项目工作绩效域涉及项目工作相关的活动和职能。 预期目标 1、高效且有效的项目绩效 2、适合项目和环境的项目过程 3、干系人适当的沟通和参与 …

【Linux】详解线程控制之线程创建线程终止线程等待线程分离

一、线程创建 thread&#xff1a;这是一个指向pthread_t类型的指针&#xff0c;用于获取新创建线程的线程ID。在调用pthread_create后&#xff0c;这个指针会被设置为新线程的ID。 attr&#xff1a;这是一个指向pthread_attr_t类型的指针&#xff0c;用于设置线程的属性&#x…

【OpenGL纹理】纹理贴图基础知识(01/4)

文章目录 一、说明二、贴图的初始化处理2.1 贴图中的几种纹理2.2 原始数据处理 - 贴图的规格化 三、纹理对象生成和绑定&#xff08;选中&#xff09;3.1 生成纹理矩阵3.2 glGenTextures 函数明细3.2 glBindTexture函数明细 四、glTexParameteri函数4.1 贴放放法参数确定4.2 放…

科研——ICONIP论文修改和提交

文章目录 Springer Nature Code of Conduct and Book Publishing Policies行为准则和出版的道德规范文章的准备Structing Your paperLengths of Paper文章长度FontsPage Numbering and Running HeadsFigures and TablesFormulaeFootnotesCitation by Number Additional Informa…

使用Flask Swagger自动生成API文档

文章目录 安装Flask Swagger使用Flask Swagger生成API文档总结1. 自动化文档生成2. 交互式文档展示3. 规范化API设计4. 提升协作效率5. 支持多种格式 Flask Swagger是一种用于管理Flask API文档的工具。它基于OpenAPI规范&#xff0c;可以自动生成API的交互式文档。使用Flask S…

【前端】从手动部署到自动部署:前端项目进化之路

从手动部署到自动部署&#xff1a;前端项目进化之路 在前端开发的领域内&#xff0c;部署是一个不可忽视的环节。随着项目复杂度的增加和线上更新频率的提升&#xff0c;手动部署逐渐暴露出它的弊端。本文将带你从手动部署过渡到自动部署&#xff0c;完成前端项目进化的重要一…

【笔记】软件架构师要点记录(1)

【笔记】软件架构师要点记录 20240517 20240517 连续性&#xff1a;恢复能力&#xff1b;可用性&#xff1a;保持稳定态的时长 增量开发模式&#xff1a;在增量开发中&#xff0c;每个增量都有明确的范围和功能&#xff0c;并按照特定的功能顺序完成。增量之间的范围划分在开发…

【C++】牛客——OR64 求和

✨题目链接&#xff1a; OR64 求和 ✨题目描述 输入两个整数 n 和 m&#xff0c;从数列1&#xff0c;2&#xff0c;3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来 ✨输入描述: 每个测试输入包含2个整数,n和m ✨输出描述: 按每个组合的字典序排列…

作业-day-240523

思维导图 知识点问答 1、IO多路复用的原理 1、创建一个检测文件描述符的容器 fd_set fds; 2、将需要检测的文件描述符放入容器中 FD_SET(文件描述符&#xff0c;&fds); 3、通过一个阻塞函数阻塞等待容器中是否有事件产生&#xff0c;如果有一个或多个事件产生&#xff0c…

由于找不到mfc140u.dll怎么办,介绍5种靠谱有效的解决方法

当您的电脑显示“mfc140u.dll丢失”的错误时&#xff0c;通常是因为系统中缺少了某个必要的动态链接库文件。这个问题可能会导致某些应用程序无法正常运行&#xff0c;给用户带来困扰。下面我将详细介绍解决该问题的五种方法。 一&#xff0c;关于mfc140u.dll文件的概述 mfc14…

OneAPI接入本地大模型+FastGPT调用本地大模型

将Ollama下载的本地大模型配置到OneAPI中&#xff0c;并通过FastGPT调用本地大模型完成对话。 OneAPI配置 新建令牌 新建渠道 FastGPT配置 配置docker-compose 配置令牌和OneAPI部署地址 配置config.json 配置调用的渠道名称和大模型名称 {"systemEnv": {&qu…

mainwindow 无菜单栏 可拖动,边界可扩大,动画浮现上边框

mainwindow 无菜单栏 可拖动,边界可扩大,动画浮现上边框 #ifndef ANIMATIONWIN_H #define ANIMATIONWIN_H #include namespace Ui {class animationWin; } class animationWin : public QWidget {Q_OBJECT public: explicit animationWin(QWidget *parent = nullptr); …

Linux 配置SSH免密登录(SSH互信)

有时候两台或多台主机之间我们希望可以进行免密登录&#xff0c;其实SSH有提供这样的功能&#xff0c;只需三步。首先在SSH服务端配置允许公钥私钥配对认证&#xff0c;然后在客户端生成公钥&#xff0c;最后将客户端的公钥上传到服务端。这样就可以从客户端免密登录服务端特定…

一文带你了解所有常用排序算法

目录 快速排序 堆排序 桶排序 归并排序 拓扑排序 本文主要介绍那些我在刷题过程中常用到的排序算法: 快速排序,堆排序,桶排序,归并排序,拓扑排序 其余算法例如冒泡,插入这种效率特别低的算法就不介绍了,用的可能性极小 每一个算法都将采用例题加解释的方式进行介绍 快速…

C++语法|虚函数与多态详细讲解系列(包含多重继承内容)

这几天把一些书籍课程&#xff0c;还有一些个人感悟整理了一个合集&#xff0c;算是把C面向对象编程中最让人感到疑惑的内容做了一个总结&#xff0c;文章导读如下&#xff1a; C语法&#xff5c;虚函数与多态详细讲解&#xff08;一&#xff09;&#xff5c;再谈构造函数&…

中科大6系+先研院+中南大学电子信息学院2023年保研经历

中科大6系 英语口语问题&#xff1a; What’s your research plan&#xff1f;Please introduce your project. 专业课问题&#xff1a; BPSK和QPSK每个字母代表的含义&#xff1f;QAM的星座图是什么样的&#xff1f;根据什么准则画成那个样子&#xff1f; 中科大先研院 …

行业首发 | MS08067-SecGPT(送邀请码)

一、简介 MS08067-SecGPT基于LLM大模型技术专门为网络安全领域设计的智能助手&#xff0c;集问答、分析、工具为一体的对话式安全专家&#xff0c;支持可以创建多会话问答。目的是辅助用户完成网络安全相关的工作&#xff0c;学员通过问答方式体验到SecGPT所具备的威胁情报分…