闭包的理解?闭包使用场景
说说你对闭包的理解?闭包使用场景

#一、是什么
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)
也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域
在 JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁
下面给出一个简单的例子
function init() {var name = "Mozilla"; // name 是一个被 init 创建的局部变量function displayName() { // displayName() 是内部函数,一个闭包alert(name); // 使用了父函数中声明的变量}displayName();
}
init();
displayName() 没有自己的局部变量。然而,由于闭包的特性,它可以访问到外部函数的变量
#二、使用场景
任何闭包的使用场景都离不开这两点:
- 创建私有变量
- 延长变量的生命周期
一般函数的词法环境在函数返回后就被销毁,但是闭包会保存对创建时所在词法环境的引用,即便创建时所在的执行上下文被销毁,但创建时所在词法环境依然存在,以达到延长变量的生命周期的目的
下面举个例子:
在页面上添加一些可以调整字号的按钮
function makeSizer(size) {return function() {document.body.style.fontSize = size + 'px';};
}var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
#柯里化函数
柯里化的目的在于避免频繁调用具有相同参数函数的同时,又能够轻松的重用
// 假设我们有一个求长方形面积的函数
function getArea(width, height) {return width * height
}
// 如果我们碰到的长方形的宽老是10
const area1 = getArea(10, 20)
const area2 = getArea(10, 30)
const area3 = getArea(10, 40)// 我们可以使用闭包柯里化这个计算面积的函数
function getArea(width) {return height => {return width * height}
}const getTenWidthArea = getArea(10)
// 之后碰到宽度为10的长方形就可以这样计算面积
const area1 = getTenWidthArea(20)// 而且如果遇到宽度偶尔变化也可以轻松复用
const getTwentyWidthArea = getArea(20)
#使用闭包模拟私有方法
在JavaScript中,没有支持声明私有变量,但我们可以使用闭包来模拟私有方法
下面举个例子:
var Counter = (function() {var privateCounter = 0;function changeBy(val) {privateCounter += val;}return {increment: function() {changeBy(1);},decrement: function() {changeBy(-1);},value: function() {return privateCounter;}}
})();var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */
上述通过使用闭包来定义公共函数,并令其可以访问私有函数和变量,这种方式也叫模块方式
两个计数器 Counter1 和 Counter2 是维护它们各自的独立性的,每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境,不会影响另一个闭包中的变量
#其他
例如计数器、延迟调用、回调等闭包的应用,其核心思想还是创建私有变量和延长变量的生命周期
#三、注意事项
如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响
例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。
原因在于每个对象的创建,方法都会被重新赋值
function MyObject(name, message) {this.name = name.toString();this.message = message.toString();this.getName = function() {return this.name;};this.getMessage = function() {return this.message;};
}
上面的代码中,我们并没有利用到闭包的好处,因此可以避免使用闭包。修改成如下:
function MyObject(name, message) {this.name = name.toString();this.message = message.toString();
}
MyObject.prototype.getName = function() {return this.name;
};
MyObject.prototype.getMessage = function() {return this.message;
};相关文章:
闭包的理解?闭包使用场景
说说你对闭包的理解?闭包使用场景 #一、是什么 一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure&#…...
openssl3.2 - 帮助文档的整理
文章目录 openssl3.2 - 帮助文档的整理概述笔记整理后, 非空的文件夹如下整理后, 留下的有点用的文件列表如下备注END openssl3.2 - 帮助文档的整理 概述 openssl3.2源码工程编译安装完, 对于库的使用者, 有用的文档, 远不止安装的那些html. 用everything查找, 配合手工删除,…...
中移(苏州)软件技术有限公司面试问题与解答(5)—— Linux进程调度参数调优是如何通过代码实际完成的1
接前一篇文章:中移(苏州)软件技术有限公司面试问题与解答(0)—— 面试感悟与问题记录 本文对于中移(苏州)软件技术有限公司面试问题中的“(11)Linux进程调度参数调优是如…...
初识C语言·文件操作
目录 1 关于文件 i)文件的基本知识 ii)数据文件的分类 2 文件打开和关闭 i)流和标准流 ii)文件指针 iii)文件打开和关闭 3 文件的顺序读写 i) fgetc fputc ii) fgets fputs iii) fscanf fprintf iv) fwrite fread 4 对比一组函数 scanf/fscanf/sscanf/printf/fpri…...
跨境卖家:如何利用自养号测评抢占市场先机?
在当今的跨境电商领域,产品的销量和评价是影响产品在市场上的表现的关键因素。对于卖家而言,自行养号进行产品测评不仅有助于提升销量,更成为了他们在这个竞争激烈的市场中保持竞争力的必备策略。 相较于一些卖家仍然依赖于服务商进行测评&a…...
开发手札:Github Timeout 22
今天(2024.01.26日),提交github又出现了ssh connect timeout errorcode 22,不论是创建新的sshkey还是配置.ssh/config都没用。 偶然在知乎上看到了解决方案,只需要在host中添加: 140.82.113.4 githu…...
学习鸿蒙基础(3)
1.组件重用样式 如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,可以采用公共样式进行复用的装饰器Styles。 Styles装饰器可以将多条样式设置…...
2024/1/27 备战蓝桥杯 1-2
目录 金币 0金币 - 蓝桥云课 (lanqiao.cn) 天干地支 0天干地支 - 蓝桥云课 (lanqiao.cn) 明明的随机数 0明明的随机数 - 蓝桥云课 (lanqiao.cn) 浇灌 0灌溉 - 蓝桥云课 (lanqiao.cn) 金币 0金币 - 蓝桥云课 (lanqiao.cn) 思路:放两种情况(k:代…...
【PyQt】02-基本UI
文章目录 前言一、首先了解什么是GUI?二、初学程序1.界面展示代码运行结果 2.控件2.1按钮展示代码运行结果 2.2 纯文本和输入框代码运行结果 3、重新设置大小 -resize4、移动窗口-move()5、设置界面在电脑中央5.1 代码运行结果 6、设置窗口图标代码运行结果 7、布局…...
无需 Root 卸载手机预装软件,精简过的老年机又行了
基础准备 准备目标手机、USB 数据线、以及一台电脑。手机 USB 连接电脑,开发者选项中打开 USB 调试。(开发者选项默认隐藏,需要在关于手机中多次点击版本号才能调出)。 安装手机驱动,下载安装 ADB 工具包。 开始操作…...
【Spring连载】使用Spring Data访问Redis(一)----快速指南
【Spring连载】使用Spring Data访问Redis(一)----快速指南 一、导入依赖二、Hello World程序 一、导入依赖 在pom.xml文件加入如下依赖就可以下载到spring data redis的jar包了: <dependency><groupId>org.springframework.boot…...
Redis 学习笔记 2:Java 客户端
Redis 学习笔记 2:Java 客户端 常见的 Redis Java 客户端有三种: Jedis,优点是API 风格与 Redis 命令命名保持一致,容易上手,缺点是连接实例是线程不安全的,多线程场景需要用线程池来管理连接。Redisson&…...
React Native
学习目标 解决以下问题: 1.什么是 React Native ?为什么它的名字中有 “Native” 字样? 2.为什么 React Native 如此之酷? 3.我们可以分别使用 React Native 和 React 来开发什么? 4.为什么会出现 ReactDOM ?它是做什…...
分布式搜索引擎_学习笔记_3
分布式搜索引擎03 0.学习目标 1.数据聚合 **聚合(aggregations)**可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎?这些手机的平均价格、最高价格、最低价格?这些手机每月的销售…...
机器学习系列——(二)主要任务
导语: 随着信息时代的到来,机器学习作为一项重要技术正逐渐渗透到我们的生活和工作中。它的主要任务是通过使用数据和算法,让计算机系统从中学习并改进性能,使其能够更智能地处理问题和做出决策。本文将详细介绍机器学习的主要任…...
十分钟快速上手Spring Boot与微信小程序API接口的调用,快速开发小程序后端服务
1.1 微信小程序API接口介绍 微信小程序API接口是连接小程序前端与后端服务器的桥梁,它提供了丰富的功能接口,包括用户信息、支付、模板消息、数据存储等。这些API接口能够满足开发者在小程序中实现各种复杂业务逻辑的需求。 用户信息接口 用户信息接口…...
理想架构的高回退Doherty功率放大器理论与ADS仿真-Multistage
理想架构的高回退Doherty功率放大器理论与仿真-Multistage 参考: 三路Doherty设计 01 射频基础知识–基础概念 Switchmode RF and Microwave Power Amplifiers、 理想架构的Doherty功率放大器(等分经典款)的理论与ADS电流源仿真参考&#x…...
<网络安全>《11 网络安全审计系统》
1 概念 审计是对资料作出证据搜集及分析,以评估企业状况,然后就资料及一般公认准则之间的相关程度作出结论及报告。 国际互联网络安全审计(网络备案),是为了加强和规范互联网安全技术防范工作,保障互联网…...
飞桨paddlespeech语音唤醒推理C INT8 定点实现
前面的文章(飞桨paddlespeech语音唤醒推理C定点实现)讲了INT16的定点实现。因为目前商用的语音唤醒方案推理几乎都是INT8的定点实现,于是我又做了INT8的定点实现。 实现前做了一番调研。量化主要包括权重值量化和激活值量化。权重值由于较小且…...
go 面试题分享
1 判断字符串中字符是否全都不同 问题描述 请实现一个算法,确定一个字符串的所有字符【是否全都不同】。这里我们要 求【不允许使用额外的存储结构】。给定一个string,请返回一个bool 值,true代表所有字符全都不同,false代表存在相同的字…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
DeepSeek越强,Kimi越慌?
被DeepSeek吊打的Kimi,还有多少人在用? 去年,月之暗面创始人杨植麟别提有多风光了。90后清华学霸,国产大模型六小虎之一,手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水,单月光是投流就花费2个亿。 疯…...
边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...
RabbitMQ 各类交换机
为什么要用交换机? 交换机用来路由消息。如果直发队列,这个消息就被处理消失了,那别的队列也需要这个消息怎么办?那就要用到交换机 交换机类型 1,fanout:广播 特点 广播所有消息:将消息…...
