闭包用运。

闭包在JavaScript编程中有多种实用场景,以下列举几个常见的闭包使用场景并附上相应的代码示例:

不使用 new 关键字调用构造函数时,构造函数内部的 this 关键字会指向全局对象(在浏览器中通常是 window 对象)。此时,构造函数的返回值取决于函数体中的代码逻辑。如果函数体中没有显式地返回一个对象,则返回 undefined

function Counter() {let count = 0; // 私有变量const aaa = () => {console.log(count);// return `1221`;};// 公共接口(闭包)return {bbb: function () {count++;},aaa: aaa, // 将aaa函数作为属性返回};
}
const counter = Counter();
counter.aaa(); // 0 只是执行了
console.log(counter.aaa(), "[["); //0 undefined  [[
// 执行后输出0, 并没有返回值输出undefined, 最后输出[[
console.log(counter.count); //undefined 私有变量,没有返回,无法直接访问
0
0 undefined [[
undefined

使用class来改造,很明显不需要return就可以访问

使用 new 关键字调用构造函数时,会创建一个新的对象,并将该对象作为 this 关键字的值传递给构造函数。然后构造函数会在这个新对象上添加属性和方法,并最终将该对象作为返回值返回。这样创建的对象是构造函数的一个实例,具有构造函数所定义的属性和方法。

class Counter {constructor() {this.count = 0; // 私有变量}increment() {this.count++;}decrement() {this.count--;}getCount() {return this.count;}
}const counterInstance = new Counter();
counterInstance.increment();
console.log(counterInstance.getCount()); // 输出: 1

1. 模块化开发与私有变量封装

闭包可以用来模拟私有变量和方法,实现模块化的封装。外部代码无法直接访问到闭包内部的变量,只能通过提供的公共接口进行交互。

function Counter() {let count = 0; // 私有变量// 公共接口(闭包)return {increment: function () {count++;},decrement: function () {count--;},getCount: function () {return count;},};
}const counterInstance = Counter();
counterInstance.increment();
console.log(counterInstance.getCount()); // 输出: 1

下面是soybean-admin自己封装的useBoolean:

import { ref } from 'vue';/*** boolean组合式函数* @param initValue 初始值*/
export default function useBoolean(initValue = false) {const bool = ref(initValue);function setBool(value: boolean) {bool.value = value;}function setTrue() {setBool(true);}function setFalse() {setBool(false);}function toggle() {setBool(!bool.value);}return {bool,setBool,setTrue,setFalse,toggle};
}

2. 延长变量生命周期

闭包可以保持对外部函数作用域中变量的引用,即使外部函数已经执行完毕,这些变量也不会被垃圾回收机制回收,从而延长了它们的生命周期。

function createMultiplier(factor) {return function(number) {return number * factor;};
}const double = createMultiplier(2);
const triple = createMultiplier(3);console.log(double(5)); // 输出: 10
console.log(triple(5)); // 输出: 15

在这个例子中,createMultiplier 函数虽然已经执行完毕,但其内部创建的闭包(返回的匿名函数)仍然保持着对外部函数参数 factor 的引用,因此 double 和 triple 分别保留了不同的乘数因子。

3. setTimeout、setInterval 中的异步操作与传参

原生的 setTimeout 和 setInterval 函数不能直接捕获外部作用域中的变量,通过闭包可以解决这个问题,确保回调函数访问到正确的变量值。

function delayedAlert(message, delay) {setTimeout(function() {alert(message);}, delay);
}let user = "John";
delayedAlert(user + " will see this alert in 2 seconds.", 2000);// 即使在这之后 user 变量被改变,延迟的 alert 仍显示原始值
user = "Jane";

4. 事件监听器与回调函数

在处理事件绑定或异步操作时,闭包有助于确保回调函数能够访问到正确的上下文数据。

function attachEventHandlers(elements, eventName, handlerCreator) {elements.forEach((element) => {element.addEventListener(eventName, handlerCreator(element));});
}const buttons = document.querySelectorAll('button');
const logButtonId = function(button) {return function(event) {console.log(`Clicked button with id: ${button.id}`);};
};attachEventHandlers(buttons, 'click', logButtonId);

在这个例子中,每个按钮的点击事件处理器(闭包)都绑定了对应的按钮元素,即使所有处理器共享同一个事件处理逻辑(logButtonId 函数),也能正确地输出各自按钮的 ID。

5. 遍历数组或其他集合时的迭代状态

闭包可以用于记录迭代过程中的状态,特别是在使用高阶函数(如 Array.prototype.mapArray.prototype.reduce)时。

function getRunningTotal(numbers) {return numbers.map((num, index, arr) => {const currentSum = arr.slice(0, index + 1).reduce((acc, val) => acc + val, 0);return { value: num, runningTotal: currentSum };});
}const numbers = [1, 2, 3, 4, 5];
const result = getRunningTotal(numbers);
console.log(result); // 输出: [{ value: 1, runningTotal: 1 }, { value: 2, runningTotal: 3 }, ...]

以上代码展示了如何使用闭包来计算数组中每个元素到当前位置的累计和,闭包在 map 函数的回调中捕获并维护了当前的累计值。

这些代码示例展示了闭包在不同场景下的应用,包括模块化、变量生命周期管理、异步操作、事件处理以及状态跟踪等。闭包的核心价值在于它能捕获并保持对外部作用域的访问,提供了一种灵活且安全的方式来组织和控制代码中的数据访问。

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

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

相关文章

【C语言】:字符函数和字符串函数

这里写目录标题 1、strlen的使用和模拟实现2、strcpy的使用和模拟3、strcat 的使用和模拟实现4、strcmp 的使用和模拟实现5、strncpy 函数的使用6、strncat 函数的使用7、strncmp函数的使用8、strstr 的使用和模拟实现9、strtok 函数的使用10、strerror 函数的使用11、字符分类…

C语言——关于指针运算的例题分析

1.指针运算中关于 sizeof 和 strlen 的例题分析 1. sizeof(数组名),这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩。 2. &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址。 3. 除此之外所有的数组名都表⽰…

汇编入门--基础知识(1)

1.汇编语言的概念 汇编语言是一种低级编程语言,它与计算机的机器语言非常接近,但比机器语言更易于人类阅读和理解。汇编语言是用一系列的助记符来表示机器语言的操作码和操作数。每种计算机体系结构(如x86、ARM等)都有自己的汇编语…

linux系统上做性能压力测试 —— 筑梦之路

这里主要使用stress 和 stress-ng。 简介 stress: stress 是一款简单但功能强大的工具,可对 Linux 系统施加可配置的 CPU、内存、I/O 或磁盘压力。通过模拟繁重的工作负载,系统管理员可以观察系统在压力下的表现反应。 这一工具的价值在于找出系统潜在的…

12.java openCV4.x 入门-HighGui之图像窗口显示

专栏简介 💒个人主页 📰专栏目录 点击上方查看更多内容 📖心灵鸡汤📖我们唯一拥有的就是今天,唯一能把握的也是今天建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫 🧭文…

Qt-线程2-moveToThread

0. 写在前面 Qt-线程1-Run-CSDN博客 上一篇介绍了为何要使用线程,这篇介绍第二种线程编写方式;这种方式代码写起来复杂一些,硬币总是有两个面,虽然写起来复杂,但是逻辑是很清晰的。 (1)新…

算法刷题Day29 |491.递增子序列、46.全排列、47.全排列 II

目录 0 引言1 递增子序列1.1 我的解题 2 全排列2.1 我的解题 3 全排列 II3.1 我的解题 🙋‍♂️ 作者:海码007📜 专栏:算法专栏💥 标题:算法刷题Day29 |491.递增子序列、46.全排列、47.全排列 II❣️ 寄语&…

linux安装dubboAdmin

1.环境准备: jdk-8u391-linux-x64apache-maven-3.9.6apache-tomcat-8.5.100 2.安装注册中心zookeeper zookeeper的安装看我的另一篇文章,安装完成后保持启动状态 linux安装Zookeeper的详细步骤-CSDN博客 3.安装dubboadmin 源码下载地址:R…

vue快速入门(十四)reduce求和

注释很详细&#xff0c;直接上代码 新增内容 非嵌套情况求和嵌套情况求和 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale…

C++第十五弹---string基本介绍(一)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、什么是STL 2、STL的版本 3、STL的六大组件 4、STL的重要性 5、如何学习STL 6、STL的缺陷 7、为什么学习string类 7.1、C语言中的字符串…

[C++][特殊类设计][单例模式]详细讲解

目录 1.[不能被拷贝]2.[只能在堆上创建对象]3.[只能在栈上创建对象]4.[请设计一个类&#xff0c;不能被继承]5.[只能创建一个对象(单例模式)]0. 设计模式1.单例模式2.饿汉模式3.懒汉模式4.单例对象释放问题 1.[不能被拷贝] 拷贝只会发生在两个场景中&#xff1a; 拷贝构造函数…

Google play开发者新手必看:2024最新最全的谷歌上架避坑指南

Google Play作为一个全球性的Android应用分发平台&#xff0c;吸引了无数开发者的目光。据统计&#xff0c;该平台的月活跃用户数已超过20亿&#xff0c;这无疑是一个巨大的市场。 但随着行业的发展&#xff0c;谷歌风控和审核机制不断升级&#xff0c;即便是经验丰富的开发者也…

Nginx配置文件修改结合内网穿透实现公网访问多个本地web站点

文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…

抖音评论ID提取工具|视频关键词评论批量采集软件

抖音评论ID提取工具&#xff1a;批量抓取抖音评论 抖音评论ID提取工具是一款功能强大的软件&#xff0c;可以帮助您批量抓取抖音视频下的评论信息。通过输入关键词和评论监控词&#xff0c;即可进行评论的抓取&#xff0c;并提供评论昵称、评论日期、评论内容、命中关键词以及所…

C++更改文件名称,在文件名增加字符

void ChangeName(string filename) {char flagcharacter a; // 要在文件名前添加的标志字符int filelocation 0 ; // 暂存文件名起始下标int directoryend 0 ; // 暂存文件夹名结束下标for(int i (filename.length() - 1); i>0; i--)if(filenam…

嵌入式系统在智能家居与工业自动化等领域的应用创新

嵌入式系统在智能家居与工业自动化等领域的应用创新 随着科技的飞速发展&#xff0c;嵌入式系统已经渗透到我们生活的方方面面&#xff0c;特别是在智能家居和工业自动化领域&#xff0c;嵌入式系统的应用正带来前所未有的变革和创新。本文将深入探讨嵌入式系统在这两个领域的…

【CSDN活动】人工智能:前沿科技中的创业机遇与挑战

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 人工智能&#xff1a;前沿科技中的创业机遇与挑战一、AI技术的快速发展与应用拓…

QML学习记录:并排页面切换效果的实现

定义一个ApplicationWindow窗口&#xff0c;通过添加SwipeView和PageIndicator来实现页面切换效果和显示当前页面位置的指示器。 ApplicationWindow {id:rootvisible: truewidth: 340height: 480title: qsTr("SwipeView") // 定义一个SwipeView用于页面切换效果 Swip…

Oracle ADG主备切换

文章目录 一、主库切换备库二、备库切换主库三、新备库&#xff08;原主库&#xff09;启用实时日志应用四、新主库切换日志五、查看当前主备库状态 一、主库切换备库 # 查看切换前的状态&#xff0c;确认当前从操作的是主库 select name,open_mode,switchover_status from v$…

Java每日一题

我的思路是: 通过示例我们可以判断出一共会有四种情况1.正常情况、2.负数、3.最后一位是0、4.反转后越界。 所以我就打算分为四步进行处理&#xff1a;首先我会创建两个StringBulider&#xff0c;一个用来存储原数字&#xff0c;一个用来存储结果集。 第一种情况进行处理的思路…