【JavaScript】闭包的理解

news2024/11/16 5:52:00

闭包是指在一个函数内部创建另一个函数,并且内部函数可以访问外部函数的变量、参数以及其他内部函数,即使外部函数已经执行完毕。这种机制使得内部函数保留了对外部作用域的引用,即使外部作用域已经不再活跃。

为什么闭包重要?

闭包在 JavaScript 中具有重要的用途和价值。它们可以用于创建私有变量、封装逻辑、避免全局污染等方面。另外,闭包还允许你在函数之外操作局部变量,从而为代码提供更大的灵活性和可维护性。

JavaScript 闭包的特点

  • 闭包可以访问外部函数的变量,即使外部函数已经返回了。
  • 闭包保存外部函数变量的引用,而不是实际的值。
  • 每当一个函数在另一个函数中被创建时,就会产生闭包。

JS 闭包的用途

闭包常被用于:

  • 封装 - 内部函数可以访问外部变量,但外部函数不能访问内部变量。这提供了封装和数据私密性。
  • 状态持续 - 闭包可以在函数调用之间保持状态(例如计数器)。函数的变量在调用之间持续存在。
  • 偏函数应用 - 闭包可以用于偏函数应用和柯里化函数。这涉及到创建一个捕获一些参数但保留其他参数未设置的函数。

JS 闭包的类型

1. 普通闭包

普通闭包是指一个函数内部定义了另一个函数,并且内部函数引用了外部函数的变量。这种情况下,内部函数会捕获外部函数的变量,并可以在外部函数执行完毕后继续使用。

  var outerVar = 'I am from outer';
  
  function inner() {
    console.log(outerVar);
  }
  
  return inner;
}

var closureFunction = outer();
closureFunction(); // 输出:I am from outer

2. 立即调用函数表达式(IIFE)闭包

IIFE 是一种创建闭包的常见模式。通过将函数定义包裹在括号内并立即调用它,你可以创建一个在执行后仍然具有访问外部作用域的函数。

  var privateVar = 'I am private';
  
  return function() {
    console.log(privateVar);
  };
})();

closureFunction(); // 输出:I am private

实践案例:计数器闭包

让我们通过一个实际案例来进一步理解闭包的应用。考虑一个简单的计数器,可以通过闭包来实现:

  var count = 0;
  
  return function() {
    return ++count;
  };
}

var counter = createCounter();
console.log(counter()); // 输出:1
console.log(counter()); // 输出:2
console.log(counter()); // 输出:3

互动练习

1.创建一个闭包函数,用于计算累加和。函数初始值为0,每次调用会将参数值累加到内部变量中。参考答案:

  var sum = 0;

  return function(value) {
    sum += value;
    return sum;
  };
}

var sumCalculator = createSumCalculator();
console.log(sumCalculator(5)); // 输出:5
console.log(sumCalculator(10)); // 输出:15
console.log(sumCalculator(2)); // 输出:17

2.创建一个IIFE闭包,用于生成斐波那契数列的下一个值。斐波那契数列起始为0和1,后续每个数字是前两个数字之和。参考答案:

  var a = 0;
  var b = 1;

  return function() {
    var next = a + b;
    a = b;
    b = next;
    return next;
  };
})();

console.log(fibonacciGenerator()); // 输出:1
console.log(fibonacciGenerator()); // 输出:2
console.log(fibonacciGenerator()); // 输出:3

注意事项

  • 闭包会导致内存泄漏,因为闭包保留了对外部作用域的引用,导致外部作用域的变量无法被垃圾回收机制释放。
  • 注意使用闭包时的作用域链,避免意外引用到不需要的变量。
  • 闭包不仅在浏览器中有用,在 Node.js 服务器端编程中也经常使用。

通过 API 工具调试后端接口

Apifox 是一个比 Postman 更强大的接口测试工具,Apifox = Postman + Swagger + Mock + JMeter,Apifox 支持调试 http(s)、WebSocket、Socket、gRPC、Dubbo 等协议的接口,并且集成了 IDEA 插件。在后端人员写完服务接口时,测试阶段可以通过 Apifox 来校验接口的正确性,图形化界面极大的方便了项目的上线效率。

总结

闭包是 JavaScript 中一个强大且有趣的概念,允许内部函数访问外部作用域中的变量和数据。通过创建闭包,你可以实现私有性、封装性以及更高级的编程技巧。了解闭包的工作原理并在实际项目中应用它们,将使你的 JavaScript 代码更加优雅和功能强大。

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

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

相关文章

Unity | Shader基础知识(第六集:语法<如何加入外部颜色资源>)

目录 一、本节介绍 1 上集回顾 2 本节介绍 二、语法结构 1 复习 2 理论知识 3 Shader里声明的写法 4 Properties和SubShader毕竟不是一家人 三、 片元着色器中使用资源 四、代码实现 五、全部代码 六、下集介绍 相关阅读 Unity - Manual: Writing Surface Shaders…

ES-模糊查询

模糊查询 1 wildcard 准备数据 POST demolike/_bulk {"index": {"_id": "1"} } {"text": "草莓熊是个大坏蛋" } {"index": {"_id": "2"} } {"text": "wolf 也是一个坏蛋&q…

大数据组件:Hadoop

文章目录 1、Hadoop 是什么2、Hadoop 优势3、Hadoop 组成(1)HDFS(2)YARN(3)MapReduce 架构概述(4)HDFS、YARN、MapReduce 三者关系(5)大数据技术生态体系&…

AWTK 串口屏开发(2) - 数据绑定高级用法

AWTK 串口屏 智能家居示例 1. 功能 这个例子稍微复杂一点,界面这里直接使用了 立功科技 ZDP1440 HMI 显示驱动芯片 例子中的 UI 文件和资源,重点关注数据绑定。在这里例子中,模型(也就是数据)里包括一台空调和一台咖…

STM32与Freertos入门(六)队列

1、队列介绍 队列是FreeRTOS提供的一种重要的通信机制,用于在任务之间传递数据。 FreeRTOS队列是一种先进先出(FIFO)的数据结构,用于在任务之间传递消息或数据项。它允许一个任务将数据项发送到队列,而另一个任务则可…

Linux部署MySQL5.7和8.0版本 | CentOS和Ubuntu系统详细步骤安装

一、MySQL数据库管理系统安装部署【简单】 简介 MySQL数据库管理系统(后续简称MySQL),是一款知名的数据库系统,其特点是:轻量、简单、功能丰富。 MySQL数据库可谓是软件行业的明星产品,无论是后端开发、…

Reinfocement Learning 学习笔记PartⅡ

文章目录 Reinfocement Learning六、随机近似与随机梯度下降(Stochastic Approximation & Stochastic Gradient Descent)6.1 Robbins-Monro Algorithm6.2 随机梯度下降 七、时序差分方法(Temporal-Difference Learning)7.1 TD…

[算法总结] 十大排序算法

[算法总结] 十大排序算法 简介: 本文首发于我的个人博客:尾尾部落排序算法是最经典的算法知识。因为其实现代码短,应该广,在面试中经常会问到排序算法及其相关的问题。一般在面试中最常考的是快速排序和归并排序等基本的排序算法…

想做游戏开发,我应该会点啥?

在知乎上,经常能看到类似“如何入门游戏开发”这样的问题,这篇文章,我试着概括性的对游戏开发所需要的技能做一个总结,希望大家对游戏开发能有一个基本的认识~ 游戏开发基础要求高么? 和其他程序猿一样,要…

[MySQL]数据库概述

目录 1.什么是数据库 2.数据库分类 2.1关系型数据库 2.2非关系型数据库 1.什么是数据库 我们知道,存储数据可以使用文件来存储。那么为什么我们还要大费周章的去设计和使用数据库呢? 因为文件保存数据有以下几个缺点: 1.文件的安全性不…

Failed to install one or more provisioning profiles on the device

把provision文件导入mac,双击安装provision的时候,提示:Failed to install one or more provisioning profiles on the device。 大体意思是: 未能在设备上安装一个或多个配置配置文件。请确保为此设备配置配置文件。如果没有&am…

FGSM、PGD、BIM对抗攻击算法实现

本篇文章是博主在AI、无人机、强化学习等领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在AI学…

代码随想录算法训练营 | day52 动态规划 300.最长递增子序列,674.最长连续递增子序列,718.最长重复子数组

刷题 300.最长递增子序列 题目链接 | 文章讲解 | 视频讲解 题目:给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。…

vue脚手架安装及使用

准备工作 安装node安装cnpm cnpm是npm的“廉价平替” 提高安装速度 npm install -g cnpm --registryhttps://registry.npm.taobao.org 安装脚手架 安装Vue脚手架 cnpm install -g vue/cli 用vue脚手架创建vue项目 找好创建项目的位置 创建项目 vue create test (test为项…

磁盘及文件系统(上)

这次博客我们将重点理解Ext2文件系统。 首先我们要理解什么是文件系统。 在之前我们一直理解的文件都是一个被打开的文件,而os为了能够管理这样的文件创建了struct_file这样的结构体对象在内核中描述被打开的文件,这个结构体对象中包含了被打开文件的基…

【PostgreSQL】从零开始:(一)初识PostgreSQL

从零开始:(一)初识PostgreSQL PostgreSQL数据库介绍为什么使用 PostgreSQL?那么多最终用户,云厂商为什么要贡献核心代码?基于PostgreSQL底层开发的好处:为什么要学习PostgreSQL?截止本文发布之日&#xff0…

鸿蒙系统(HarmonyOS)之方舟框架(ArkUI)介绍

鸿蒙开发官网:HarmonyOS应用开发官网 - 华为HarmonyOS打造全场景新服务 方舟开发框架(简称:ArkUI),是一套构建HarmonyOS应用界面的UI开发框架,它提供了极简的UI语法与包括UI组件、动画机制、事件交互等在内…

鸿蒙app获取文本控件按钮控件_修改控件名称_按钮触发事件_提示信息显示

鸿蒙app获取文本控件按钮控件_修改控件名称_按钮触发事件_ 点击启动:提示信息显示 package com.example.myapplication.slice;import com.example.myapplication.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; impor…

linux 文本信息查询grep;控制命令执行和管道操作符号

1、grep grep "keyword" /path/to/logfile获取查询结果最后一行 grep "runs/detect/train" test4.log | tail -n 12、linux控制命令执行和管道操作符号 &、|、; 和 &&、》、>、< ##例子&#xff1b;wandb disabled && yolo …

synchronized关键字的使用和原理

synchronized关键字的使用和原理 synchronized&#xff1a;对象锁&#xff0c;保证了临界区内代码的原子性&#xff0c;采用互斥的方式让同一时刻至多只有一个线程能持有对象锁&#xff0c;其它线程获取这个对象锁时会阻塞&#xff0c;保证拥有锁的线程可以安全的执行临界区内…