当前位置: 首页 > news >正文

闭包的概念及使用场景介绍

概念:在JavaScript中,闭包(Closure)是指一个函数有权利访问定义在它外部作用域的任何变量。

function outerFn(outerVal) {return function innerFn(innerVal) {console.log('outerVal', outerVal)console.log('innerVal', innerVal)}
}const newFunction = outerFn('outside')
newFunction('inside')
// outerVal outside
// innerVal inside

内部函数有权利访问外部作用域的变量outerVal,而外部函数的变量已经被内部函数绑定。

使用场景

  1. 数据封装和私有化
    创建私有变量:闭包可以帮助我们封装私有变量,防止外部直接访问和修改。
    模块模式:使用闭包来实现模块化代码,每个模块都有自己的作用域,不会污染全局命名空间。
    function createCounter() {let val = 0;return {increment() {val++;},getVal() {return val;}}
    }
    let counter = createCounter()
    counter.increment()
    console.log(counter.getVal())// 1
    counter.increment()
    console.log(counter.getVal())// 2
    
  2. 柯里化(Currying)
    通过闭包,可以创建一个函数,这个函数被调用时不会立即执行,而是返回一个新的函数,新函数可以访问到原函数的参数。

function curry(func) {const len = func.length;// 返回一个新函数,这个新函数会处理参数的收集return function curried(...args) {// 如果传入的参数数量足够,直接调用原始函数if(args.length >= len) {return func.apply(this, args)} else {// 如果参数数量不足,返回一个新的函数,这个函数继续收集参数return function(...args2) {return curried.apply(this, args.concat(args2))}}}
}function add(a,b,c) {return a+b+c;
}const curriedAdd = curry(add);
console.log(curriedAdd(1,2,3))// 6
console.log(curriedAdd(1)(2,3))// 6
console.log(curriedAdd(1,2)(3))// 6
  1. 高阶函数
    高阶函数可以接收函数作为参数或将函数作为返回值,闭包使得这些函数可以访问并操作外部作用域的变量。
function formatNumberToLocaleString() {return function(number) {// 将数字转换为字符串,并使用正则表达式实现千分位分割return number.toLocaleString();};}const formatThousandSeparator = formatNumberToLocaleString();// 使用闭包实例格式化数字console.log(formatThousandSeparator(1234567.89)); // 输出 "1,234,567.89"

4.实现工厂函数
工厂函数可以创建并返回一个具有特定功能的对象,闭包可以用来保持每个对象的私有状态。

function carFactory(brand) {// 私有变量let engineState = 'off';return {startEngine: function() {engineState = 'on';console.log(`${brand} engine is now ${engineState}`)},stopEngine: function() {engineState = 'off'console.log(`${brand} engine is now ${engineState}`)},}
}const ford = carFactory('ford')
ford.startEngine()// ford engine is now on
ford.stopEngine()// ford engine is now off

5.事件处理和异步操作
在事件处理或异步操作中,闭包可以用来保持对特定作用域的引用,即使是在回调函数执行时作用域已经消失。


// 假设有一个元素列表
const items = document.querySelectorAll('.item');// 创建一个闭包来处理点击事件和异步操作
function createEventHandler(itemIndex) {return function(event) {// 从服务器获取数据fetchDataFromServer(itemIndex).then(data => {console.log(`Item ${itemIndex} data:`, data);}).catch(error => {console.error(`Error fetching data for item ${itemIndex}:`, error);});};
}// 为每个项目添加事件监听器
items.forEach((item, index) => {// 使用闭包来保持 itemIndex 的状态item.addEventListener('click', createEventHandler(index));
});// 模拟从服务器获取数据的异步函数
function fetchDataFromServer(itemIndex) {return new Promise((resolve, reject) => {setTimeout(() => {// 模拟成功或失败的情况if (Math.random() > 0.5) {resolve(`Data for item ${itemIndex}`);} else {reject(new Error(`Failed to fetch data for item ${itemIndex}`));}}, 1000);});
}
  1. 迭代器和生成器
    生成器函数利用闭包来保持其在每次迭代时的状态。
function createArrayIterator(array) {let index = 0;return {next: function() {if (index < array.length) {return { value: array[index++], done: false };} else {return { done: true };}}};}const myArray = [1, 2, 3];const iterator = createArrayIterator(myArray);console.log(iterator.next()); // { value: 1, done: false }console.log(iterator.next()); // { value: 2, done: false }console.log(iterator.next()); // { value: 3, done: false }console.log(iterator.next()); // { done: true }

闭包是JavaScript最好的语法之一。

相关文章:

闭包的概念及使用场景介绍

概念&#xff1a;在JavaScript中&#xff0c;闭包&#xff08;Closure&#xff09;是指一个函数有权利访问定义在它外部作用域的任何变量。 function outerFn(outerVal) {return function innerFn(innerVal) {console.log(outerVal, outerVal)console.log(innerVal, innerVal)…...

qt5将程序打包并使用

一、封装程序 (1)、点击创建项目->库->clibrary &#xff08;2&#xff09;、填写自己想要封装成库的名称&#xff0c;这里我填写的名称为mydll1 &#xff08;3&#xff09;、如果没有特殊的要求&#xff0c;则一路下一步&#xff0c;最终会出现如下文件列表。 (4)、删…...

软件设计师-上午题-15 计算机网络(5分)

计算机网络题号一般为66-70题&#xff0c;分值一般为5分。 目录 1 网络设备 1.1 真题 2 协议簇 2.1 真题 3 TCP和UDP 3.1 真题 4 SMTP和POP3 4.1 真题 5 ARP 5.1 真题 6 DHCP 6.1 真题 7 URL 7.1 真题 8 浏览器 8.1 真题 9 IP地址和子网掩码 9.1 真题 10 I…...

uniapp上拉刷新下拉加载

方法一&#xff1a; z-paging 的组件库&#xff1a; show-loading-more-no-more-view"false" 该属性控制是否显示 "加载更多" 或 "没有更多" 的提示。如果设为 false&#xff0c;则不会显示这些提示。如果设为 true&#xff0c;当数据加载完毕…...

【C++】【算法基础】快速排序

快速排序 题目 用快速排序排序长度为 n n n的整数数列。 题解 快速排序的核心思想是分而治之&#xff1a;选定一个基准值&#xff0c;将数组分为两半&#xff0c;一边比其小&#xff0c;一边比其大&#xff0c;然后再次分别选定一个基准值&#xff0c;再次操作。 #include…...

数仓工具—Hive语法之窗口函数中的order by

窗口函数中的order by 其实工作这么多年了,再加上写了这么多的文章,我觉得我还是很理解窗口函数这个东西了,毕竟在工作中用了这么多,各种row_number 排序求分组前几,各种lead/lag 代替自关联实现感觉已经得心应手了。 但是最近遇到窗口函数中的order by 的问题,然后我发…...

以旅游产品为例改写一篇系统架构风格的论文

概念: 系统架构风格是描述某一特定应用领域中系统组织方式的惯用模式,架构风格定义了一个词汇表和一组约束,词汇表中包含一些构件和连接件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的,软件系统架构风格反应了领域中众多软件系统所共有的结构和语义特性,…...

【Linux】linux编辑器-vim的命令及配置

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…...

解决vite项目tailwindcss不生效!!(Vue3、tailwindcss失效)

安装tailwindcss vite自带安装了postcss&#xff0c;只需要安装tailwindcss npm install -D tailwindcss自动创建tailwind.config.js npx tailwindcss init -p/** type {import(tailwindcss).Config} */ module.exports {// 配置需要使用tailwindcss的文件content: [./src/vi…...

ubuntu 20.04 NVIDIA驱动、cuda、cuDNN安装

1. NVIDIA驱动 系统设置->软件和更新->附加驱动->选择NVIDIA驱动->应用更改。该界面会自动根据电脑上的GPU显示推荐的NVIDIA显卡驱动。 运行nvidia-smi: NVIDIA-SMI has failed because it couldnt communicate with the NVIDIA driver. Make sure that the lat…...

Python世界:力扣题704二分查找

Python世界&#xff1a;力扣题704二分查找 任务背景思路分析代码实现测试套件本文小结 任务背景 问题来自力扣题目704&#xff1a;Binary Search&#xff0c;大意如下&#xff1a; Given an array of integers nums which is sorted in ascending order, and an integer target…...

W55RP20-EVB-Pico评估板介绍

目录 1 简介 2 硬件资源 2.1 硬件规格 2.2 引脚定义 2.3 工作条件 3 参考资料 3.1 RP2040 数据手册 3.2 原理图 ​编辑 原理图 & 物料清单 & Gerber 文件 3.3 尺寸图&#xff08;单位&#xff1a;mm&#xff09; ​编辑 3.4 认证 3.5 参考例程 4 硬件协…...

Flink安装和Flink CDC实现数据同步

一&#xff0c;Flink 和Flink CDC 1&#xff0c; Flink Apache Flink是一个框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行有状态计算。 中文文档 Apache Flink Documentation | Apache Flink 官方文档 &#xff1a;https://flink.apache.org Flink 中文社区…...

数字化转型助手 快鲸SCRM系统为企业营销赋能

内容概要 在当今这个快速变化的商业环境中&#xff0c;数字化转型已经成为企业生存与发展的关键要素。无论是零售、制造还是服务行业&#xff0c;企业都深刻意识到传统工作模式的局限性&#xff0c;必须借助先进的技术来优化运营和提升客户体验。快鲸SCRM系统就是这样一款数字…...

浅谈Agent

目录 什么是大模型 Agent &#xff1f; 大模型Agent 有哪些部分组成? 规划&#xff08;Planning&#xff09; Planning类型 不依赖反馈的计划 基于反馈的计划 拆解子目标和任务分解方法 COT TOT GOT LLMP 反思和完善 ReAct(融合推理与执行的能力) Reflexion(动态…...

绿色能源发展关键:优化风电运维体系

根据QYResearch调研团队最新发布的《全球风电运维市场报告2023-2029》显示&#xff0c;预计到2029年&#xff0c;全球风电运维市场的规模将攀升至307.8亿美元&#xff0c;并且在接下来的几年里&#xff0c;其年复合增长率&#xff08;CAGR&#xff09;将达到12.5%。 上述图表及…...

Sparrow系列拓展篇:对调度层进行抽象并引入IPC机制信号量

前言 在笔者更新完Sparrow手把手教学系列后&#xff0c;原本是不打算继续更新的。但关于Sparrow系列的读者又渐渐增多&#xff0c;作为作者&#xff0c;总感觉这个系列的文章还是稍微有些不圆满&#xff0c;恐怕多少会让读者有些意兴阑珊。 最近又恰好有一点空闲时间&#xf…...

天塌了!!!SQL竟也可以做预测分析?| 商品零售额的预测

目录 0 问题背景 1 数据准备 2 问题解决 2.1 模型构建 &#xff08;1&#xff09;符号规定 &#xff08;2&#xff09;基本假设 &#xff08;3&#xff09;模型的分析与建立 2.2 模型求解 3 小结 0 问题背景 1960年—1985年全国社会商品零售额如图1 所示 表1全国社…...

VSCode本地C/C++环境配置

基本环境下载 1.我的系统是windows&#xff0c;自己先下载安装VSCode&#xff0c;网上视频实在太多&#xff0c;我建议跟着B站视频操作。 2.下载安装好后你需要明白&#xff1a;VSCode只是一个编辑工具&#xff0c;我们要写C/C代码得编译运行&#xff0c;所以我们要配置它在w…...

【智能算法应用】淘金优化算法求解二维路径规划问题

摘要 本文基于智能算法的淘金优化算法&#xff08;Gold Panning Optimization, GPO&#xff09;求解二维路径规划问题。该算法模拟淘金过程中个体寻找最优金矿路径的行为&#xff0c;利用适应度函数优化路径规划&#xff0c;能够在复杂环境下实现从起点到目标点的最优路径搜索…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...

NamedParameterJdbcTemplate 使用方法及介绍

NamedParameterJdbcTemplate是 Spring 框架中用于数据库操作的核心类之一&#xff0c;它拓展了JdbcTemplate&#xff0c;通过封装实现命名参数特性&#xff0c;相比传统占位符?&#xff0c;命名参数可读性和维护性更强&#xff0c;能有效避免参数顺序混淆问题。 一、核心支持…...

跑通 TrackNet-Badminton-Tracking-tensorflow2 项目全记录

&#x1f4dd; 跑通 TrackNet-Badminton-Tracking-tensorflow2 项目全记录 git clone https://github.com/Chang-Chia-Chi/TrackNet-Badminton-Tracking-tensorflow2.git TrackNet-Badminton-Tracking-tensorflow2 conda create --prefix /cloud/TrackNet-Badminton-Tracking-…...