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

闭包的定义与作用(含举例)

闭包

1.什么是闭包

闭包 是指在一个函数内部定义的函数可以访问该函数作用域内的变量,及时在外部函数执行完毕后,内部函数仍然可以访问到这些变量。 换句话说,闭包使得函数可以记住并访问其词法作用域内的变量,即使在其定义的词法作用域之外执行。 (函数在定义时,他所能访问的变量都已经确定了)

2.闭包的作用

  1. 封装变量
  2. 保持状态
  3. 延长作用域链
  4. 实现回调和异步编程
  • 封装变量: 闭包可以将变量私有化,只暴露必要的接口,实现了变量的封装,增强了安全性。
function createCounter() {var count = 0;return {increment: function() {count++;},getCount: function() {return count;}};
}var counter = createCounter();
counter.increment();
console.log(counter.getCount()); // 输出:1

createCounter 函数返回一个对象,该对象包含两个方法 incrementgetCount,这两个方法都可以访问 createCounter 内部的 count 变量。外部无法直接访问 count 变量,从而实现了变量的封装。

  • 保持状态: 由于闭包可以访问外部函数的变量,因此可以在函数之间共享状态,实现状态的持久化。
function createLogger(name) {return function(message) {console.log(`[${name}] ${message}`);};
}var infoLogger = createLogger('INFO');
infoLogger('This is an info message.'); // 输出:[INFO] This is an info message.

在这个例子中,createLogger 函数返回一个函数,这个返回的函数被称为日志记录器。每次调用 createLogger 时,都会创建一个新的日志记录器,并且这个日志记录器可以记住传入 createLoggername 参数。每个日志记录器都可以独立地记录日志,从而保持了状态。

  • 延长作用域链: 闭包可以使函数访问其定义时所在的作用域,实现对外部变量的引用,延长了作用域链。
function addSuffix(suffix) {return function(name) {return name + suffix;};
}var addLy = addSuffix('ly');
console.log(addLy('quick')); // 输出:quickly

在这个例子中,addSuffix 函数返回一个函数,该函数将给定的后缀添加到传入的名称上。addLy 函数是 addSuffix 的一个特定实例,它将 ‘ly’ 后缀添加到名称中。即使 addSuffix 函数执行完毕后,addLy 仍然可以访问传入的后缀,因为它形成了闭包,延长了作用域链。

  • 实现回调和异步编程: 闭包可以用于创建回调函数,用于处理异步任务,例如事件监听、定时器等。
function fetchData(url, callback) {// 模拟异步请求setTimeout(function() {var data = 'Some data from ' + url;callback(data);}, 1000);
}fetchData('https://example.com/api', function(data) {console.log('Data received:', data);
});

fetchData 函数执行异步请求,并在请求完成后调用传入的回调函数。这种方式允许我们将逻辑分离,使得我们的代码更具可读性和可维护性。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 在UE5中使用OverlayMaterial制作多材质效果
  • Redis Sentinel工作原理
  • 基于python+django+vue.js开发的医院门诊管理系统/医疗管理系统
  • 计算机网络Day1--计算机网络体系
  • 【计算机考研】408系统学习法
  • vue 生成word表格文档 前端库介绍
  • K8s ingress-nginx根据请求目录不同将请求转发到不同应用
  • Nginx笔记
  • 75.SpringMVC的拦截器和过滤器有什么区别?执行顺序?
  • MCAL知识点(二十七):TC275如何通过GPT12实现ABZ解码
  • Golang for 循环
  • LeetCode 2656.K个元素的最大和
  • 如何创建WordPress付款表单(简单方法)
  • 在Ubuntu中使用python
  • 【Spring】三级缓存
  • Android单元测试 - 几个重要问题
  • Java面向对象及其三大特征
  • js写一个简单的选项卡
  • leetcode98. Validate Binary Search Tree
  • Python_OOP
  • Python中eval与exec的使用及区别
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • VUE es6技巧写法(持续更新中~~~)
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • 代理模式
  • 工作中总结前端开发流程--vue项目
  • 关于for循环的简单归纳
  • 后端_ThinkPHP5
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 前端自动化解决方案
  • 延迟脚本的方式
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • # 数据结构
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • #Datawhale AI夏令营第4期#多模态大模型复盘
  • #define与typedef区别
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #每日一题合集#牛客JZ23-JZ33
  • $.ajax()参数及用法
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (c语言+数据结构链表)项目:贪吃蛇
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)创业的注意事项
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • . Flume面试题
  • .gitignore文件---让git自动忽略指定文件
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET Core中的时区转换问题
  • .NET Framework .NET Core与 .NET 的区别
  • .NET MAUI Sqlite数据库操作(二)异步初始化方法
  • .NET 给NuGet包添加Readme