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

概念:在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最好的语法之一。

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

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

相关文章

Java I/O流面试之道

先赞后看&#xff0c;Java进阶一大半 南哥在国外 stackoverflow 看到13年前的这么一个问题&#xff1a;如何使用 Java 逐行读取大型文本文件。大家有什么思路吗&#xff1f;评论区一起讨论讨论。 I need to read a large text file of around 5-6 GB line by line using Java. …

精选 Top10 开源调度工具,解锁高效工作负裁自动化

在大数据和现代 IT 环境中&#xff0c;任务调度与工作负载自动化&#xff08;WLA&#xff09;工具是优化资源利用、提升生产效率的核心驱动力。随着企业对数据分析、实时处理和多地域任务调度需求的增加&#xff0c;这些工具成为关键技术。 本文将介绍当前技术发展背景下的Top …

微软域名邮箱:如何设置管理烽火域名邮箱?

微软域名邮箱的设置技巧&#xff1f;免费域名邮箱注册设置教程&#xff1f; 微软域名邮箱为企业提供了一个强大且灵活的解决方案&#xff0c;帮助企业轻松管理其域名邮箱。烽火将详细介绍如何设置和管理微软域名邮箱&#xff0c;确保您的团队能够高效地使用这一工具。 微软域…

VS ssh连接linux无法运行的问题 GDB 的解决方法

Unable to start debugging. Program path ... is missing or invalid. GDB failed with message:/home/zsy/projects/是一个目录 把这个将解决方案和项目放在同一目录中勾选

Python酷库之旅-第三方库Pandas(203)

目录 一、用法精讲 946、pandas.IntervalIndex类 946-1、语法 946-2、参数 946-3、功能 946-4、返回值 946-5、说明 946-6、用法 946-6-1、数据准备 946-6-2、代码示例 946-6-3、结果输出 947、pandas.IntervalIndex.closed属性 947-1、语法 947-2、参数 947-3、…

Trimble X12三维激光扫描仪正在改变游戏规则【上海沪敖3D】

Trimble X12 三维激光扫描仪凭借清晰、纯净的点云数据和亚毫米级的精度正在改变游戏规则。今天的案例我们将与您分享&#xff0c;X12是如何帮助专业测量咨询公司OR3D完成的一个模拟受损平转桥运动的项目。 由于习惯于以微米为单位工作&#xff0c;专业测量机构OR3D是一家要求…

【大数据学习 | kafka】简述kafka的消费者consumer

1. 消费者的结构 能够在kafka中拉取数据进行消费的组件或者程序都叫做消费者。 这里面要涉及到一个动作叫做拉取。 首先我们要知道kafka这个消息队列主要的功能就是起到缓冲的作用&#xff0c;比如flume采集数据然后交给spark或者flink进行计算分析&#xff0c;但是flume采用的…

uniapp发布到微信小程序,提示接口未配置在app.json文件中

使用uniapp打包上传微信小程序发布&#xff0c;在提交审核时提示 “接口未配置在app.json文件中” 如下图所示 解决方法&#xff1a;在manifest.json文件中打开源码视图&#xff0c;添加 requiredPrivateInfos 字段键入所需要的接口&#xff08;数组&#xff09;

重新下载Window11系统中的mfc100.dll文件

环境 Xshell6Xftp6Window11 前言 最近下载了一款绿色版本的Xshell远程客户端软件&#xff0c;用来登录Linux服务器&#xff0c;在Window11使用&#xff0c;点击时候提示很多dll文件缺失&#xff0c;所以比较纠结&#xff0c;因为是绿色版本软件&#xff0c;所以不能重装&…

js基础篇笔记 (万字速通)

此笔记来自于黑马程序员,仅供笔者复习 JavaScript 基础 - 第1天 了解变量、数据类型、运算符等基础概念&#xff0c;能够实现数据类型的转换&#xff0c;结合四则运算体会如何编程。 体会现实世界中的事物与计算机的关系理解什么是数据并知道数据的分类理解变量存储数据的“容…

vue3+ts+element-ui实现的可编辑table表格组件 插入单行多行 组件代码可直接使用

最近需求越来越离谱&#xff0c;加班越来越严重&#xff0c;干活的牛马也越来越卑微。写了一个可编辑表格&#xff0c;并已封装好组件&#xff0c;可直接使用。 基于这位大佬的 动态表格自由编辑 方法和思路&#xff0c;于是参考和重写了表格&#xff0c;在基础上增加和删除了…

决策树(部分)

目录 信息熵 总结&#xff1a; 特征选择 信息增益&#xff1a;ID3算法 增益率&#xff1a;C4.5 基尼指数 剪枝处理 预剪枝 后剪枝 信息熵 信息熵 (entropy)是 用于度量样本集合“ 纯度 ” 最常用的一种指标&#xff0c;其中 “ 熵 ” 是事物的不确定性&#xff0c;假定…

webpack 执行流程 — 实现 myWebpack

前言 实现 myWebpack 主要是为了更好的理解&#xff0c;webpack 中的工作流程&#xff0c;一切都是最简单的实现&#xff0c;不包含细节内容和边界处理&#xff0c;涉及到 ast 抽象语法树和编译代码部分&#xff0c;最好可以打印出来观察一下&#xff0c;方便后续的理解。 re…

【python】Flask

文章目录 1、Flask 介绍2、Flask 实现网页版美颜效果3、参考 1、Flask 介绍 Flask 是一个用 Python 编写的轻量级 Web 应用框架。它设计简单且易于扩展&#xff0c;非常适合小型项目到大型应用的开发。 以下是一些 Flask 库中常用的函数和组件&#xff1a; 一、Flask 应用对…

AI大模型如何重塑软件开发流程?

《AI大模型对软件开发流程的重塑&#xff1a;变革、优势、挑战与展望》 一、传统软件开发流程与模式&#xff08;一&#xff09;传统软件开发流程&#xff08;二&#xff09;传统软件开发模式面临的问题&#xff08;一&#xff09;AI在软件开发中的应用场景&#xff08;二&…

OceanBase 应用实践:如何处理数据空洞,降低存储空间

问题描述 某保险行业客户的核心系统&#xff0c;从Oracle 迁移到OceanBase之后&#xff0c;发现数据存储空间出现膨胀问题&#xff0c;数据空间 datasize9857715.48M&#xff0c;实际存储占用空间17790702.00M。根据 required_mb - data_mb 值判断&#xff0c;数据空洞较为严重…

Zookeeper运维秘籍:四字命令基础、详解及业务应用全解析

文章目录 一、四字命令基础二、四字命令详解三、四字命令的开启与配置四、结合业务解读四字命令confconsenvi命令Stat命令MNTR命令ruok命令dump命令wchswchp ZooKeeper&#xff0c;作为一款分布式协调服务&#xff0c;提供了丰富的四字命令&#xff08;也称为四字短语&#xff…

MATLAB大数计算工具箱及其用法

1. MATLAB大数工具箱Variable Precision Integer Arithmetic介绍 Variable Precision Integer Arithmetic是John DErrico 开发的大数运算工具箱&#xff0c;可以用完全任意大小的整数进行算术运算。支持vpi定义的数组和向量。 2.MATLAB代码 完整代码见: https://download.cs…

【野生动物识别系统】Python+深度学习+人工智能+卷积神经网络算法+TensorFlow+ResNet+图像识别

一、介绍 动物识别系统&#xff0c;使用Python作为主要开发语言&#xff0c;基于深度学习TensorFlow框架&#xff0c;搭建卷积神经网络算法。并通过对18种动物数据集进行训练&#xff0c;最后得到一个识别精度较高的模型。并基于Django框架&#xff0c;开发网页端操作平台&…

数据库_SQLite3

下载 1、更新软件源&#xff1a; sudo apt-get update 2、下载SQLite3&#xff1a; sudo apt-get install sqlite3 3、验证&#xff1a; sqlite3启动数据库&#xff0c;出现以下界面代表运行正常。输入 .exit 可以退出数据库 4、安装sqlite3的库 sudo apt-get install l…