当前位置: 首页 > 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;能够在复杂环境下实现从起点到目标点的最优路径搜索…...

主流开源License深度解析:从BSD到CC的适用场景与商业考量

1. 开源许可证的本质与核心价值 第一次接触开源许可证时&#xff0c;我和大多数人一样困惑&#xff1a;为什么明明是我的代码&#xff0c;却需要别人来告诉我怎么使用&#xff1f;后来在参与多个开源项目后才发现&#xff0c;许可证就像代码世界的交通规则&#xff0c;它不是为…...

OpenClaw 3.28重磅发布:Grok搜索内置,高危操作迎来“保命”拦截机制

引言&#xff1a; 不仅仅是“草台”后的补救&#xff0c;更是智能体操作系统的成人礼 就在前两天&#xff0c;OpenClaw 之父 Peter 的一次“漏打包”操作&#xff0c;直接导致 3.22 版本大面积白屏&#xff0c;让无数开发者以为自己辛辛苦苦养了一周的“赛博小龙虾”就这么“死…...

机器人状态估计——从IMU运动方程到ESKF误差状态建模(上)

1. 从IMU数据到机器人状态估计的挑战 当你第一次拿到一个IMU传感器时&#xff0c;可能会觉得它就像个魔法黑盒——只要把它装在机器人上&#xff0c;就能知道机器人的姿态、速度和位置。但实际操作起来&#xff0c;你会发现IMU数据就像个调皮的孩子&#xff0c;稍不注意就会给你…...

【由浅入深探究langchain】第十七集-构建你的首个 RAG 知识库助手(从文档索引到检索增强生成)

前言在大语言模型&#xff08;LLM&#xff09;爆火的今天&#xff0c;我们常常会被 GPT 或 Claude 展现出的博学所惊叹。然而&#xff0c;当你试着问它“我公司昨晚新发布的财务报表数据是多少&#xff1f;”或者“我上周在笔记里写的某个私人计划是什么&#xff1f;”时&#…...

(ubuntu黑屏)Z890M + U7 265KF + RTX 5070 Ti 安装 Ubuntu 22.04.5 实战记录(网卡 + 显卡驱动全解)

本文记录了在技嘉 Z890M Intel Core Ultra 7 265KF RTX 5070 Ti 新平台上&#xff0c;成功安装 Ubuntu 22.04.5 并解决网卡、显卡驱动问题的完整过程&#xff0c;适合同类配置参考。一、硬件环境组件型号主板技嘉 Z890M 小雕&#xff08;带 WiFi&#xff09;CPUIntel Core Ul…...

突破Twitter数据限制:Rettiwt-API开源工具零成本数据获取指南

突破Twitter数据限制&#xff1a;Rettiwt-API开源工具零成本数据获取指南 【免费下载链接】Rettiwt-API An API for fetching data from Twitter for free! 项目地址: https://gitcode.com/gh_mirrors/re/Rettiwt-API 在社交媒体数据驱动决策的时代&#xff0c;Twitter作…...

Zenith.NET v0.0.6 发布 [特殊字符] — API 大幅精简,为 Metal 后端铺路

项目简介 Zenith.NET 是一个现代的、跨平台的 .NET 图形与计算库&#xff0c;旨在为 .NET 开发者提供统一的 GPU 编程接口。无论你是要做高性能渲染、图形应用&#xff0c;还是 GPU 通用计算&#xff0c;Zenith.NET 都能帮你屏蔽底层 API 的差异&#xff0c;让代码在不同平台上…...

LiuJuan20260223Zimage与Typora协作:智能化Markdown文档创作

LiuJuan20260223Zimage与Typora协作&#xff1a;智能化Markdown文档创作 每次打开Typora&#xff0c;看着那个简洁到极致的界面&#xff0c;我都会有种创作的冲动。但冲动归冲动&#xff0c;真到了要写一篇技术博客、整理一份项目文档&#xff0c;或者梳理一堆零散笔记的时候&…...

手把手教你实现UE4与Vue页面的无缝通信(附完整代码示例)

UE4与Vue深度整合&#xff1a;现代前端框架与游戏引擎的通信实践 在数字内容开发领域&#xff0c;将现代Web技术与游戏引擎结合已成为提升用户体验的重要趋势。本文将深入探讨如何实现Unreal Engine 4与Vue.js框架的高效通信&#xff0c;为开发者提供一套完整的解决方案。 1.…...

保姆级教程:用星图AI平台训练PETRV2-BEV模型,新手也能玩转自动驾驶

保姆级教程&#xff1a;用星图AI平台训练PETRV2-BEV模型&#xff0c;新手也能玩转自动驾驶 1. 前言&#xff1a;为什么你需要这篇教程&#xff1f; 如果你对自动驾驶技术感兴趣&#xff0c;想亲手训练一个能“看懂”周围环境的AI模型&#xff0c;但又被复杂的代码、昂贵的硬件…...