04-闭包

news2024/11/27 3:50:34

闭包:函数嵌套函数,内部函数就是闭包,只有函数内部的子函数才能读取内部变量。

先上一个经典的闭包:

function outerFun () {
	let a = 10;
	function innerFun () {
		console.log(a);
	}
	return innerFun;
}
let fun = outerFun();
fun(); //10

将内部函数作为外部函数的返回值;

特性:

内部函数没有执行完成,外部函数变量不会销毁。

形成一个不销毁的私有作用域,除了保护私有变量不受干扰以外,还可以存储一些内容。

作用域链:

我们⼀般将作⽤域分成:

  • 全局作用域
  • 局部作用域,就是函数作用域,只能在函数内部访问,不能在函数以外去访问
  • 块级作用域,⼤括号中使⽤ let 和 const 声明的变量存 在于块级作⽤域中。在⼤括号之外不能访问这些变量

例1:

let a = 10;
let b = 20;
function fun() {
	let a = 30;
	let c = 40;
	function fn() {
		let a = 50;
		let d = 60;
		function f() {
			console.log(b);
		}
	}
}

 

 正常情况下,函数执行完成,内部变量会自动销毁(释放内存空间)

在函数内部可以访问内部定义的变量

function fun() {
	let a = 10;
	console.log(a); //10
}
fun(); 

在函数外部不能访问到函数里面定义的变量,因为函数执行完成,变量就销毁了

function fun() {
	let a = 10;
}
fun(); 
console.log(a); //a is not defined

闭包的作用:

保存,保存外部函数和私有变量

保护,内部变量私有化,不会像全局变量受污染

模块化,团队协作开发时,使用闭包可以让各自的代码存储在私人范围内,避免变量冲突

闭包有两大作用:保存和保护

1) 保存:

函数执行形成一个私有作用域,函数执行完成,当前私有作用域(栈内存)中的某一部分内容被栈内存以外的其他东西(变量/元素的事件)占用了,当前占内存不能被释放掉,也就形成了不销毁的私有作用域(里面的私有变量也不会被销毁)

函数执行返回了一个引用数据类型堆内存地址(并且堆内存隶属于这个作用域),在外面有一个变量接收了这个返回值,此时当前作用域就不能被销毁(想要销毁,只需要放外面的变量赋值为null,也就是不占用当前作用域中的内容了)

2) 保护:

形成私有作用域,保护里面的私有变量不受外界干扰
例如:团队协作开发,每个开发者把自己代码存放在一个私有作用域当中,防止相互之间的冲突;把需要共别人使用的方法,通过return或者window.XXX暴露在全局下即可(比如jQuery源码种也是利用保护机制实现的)

真实项目中,我们利用这种保护机制,实现团队协作开发(避免多人用同一个命名,导致代码冲突的问题)

闭包使用场景

1、setTimeout()

原生的setTimeout传递的第一个函数不能带参数,通过闭包可以实现传参效果。

function f1(a) {
	function f2() {
		console.log(a);
	}
	return f2;
}
let fun1 = f1(1);
setTimeout(fun1, 1000); // 1秒后打印1

2、回调

定义行为,然后把它关联到某个用户事件上。代码通常会作为一个回调(事件触发时调用的函数)绑定到事件。

例:点击字体改变大小

<body>
	<a href="#" id="size-12">12</a>
	<a href="#" id="size-20">20</a>
	<a href="#" id="size-30">30</a>
</body>
<script>
	function changeSize(size) {
		return function() {
			document.body.style.fontSize = size + 'px'
		}
	}
	let size12 = changeSize(12);
	let size20 = changeSize(20);
	let size30 = changeSize(30);
	document.getElementById('size-12').onclick = size12;
	document.getElementById('size-20').onclick = size20;
	document.getElementById('size-30').onclick = size30;
</script>

3、函数防抖

  • 如果timer为true,说明正在计时且触发了相同事件,所以要取消当前的计时,重新计时
  • 否则就表示没有在计时,就开启一个计时
function debounce(fn, delay) {
	let timer = null;
	return function() {
		if (timer) {
			clearTimeout(timer)
			timer = setTimeout(fn, delay);
		} else {
			timer = setTimeout(fn, delay);
		}
	}
}

4、封装私有变量

function add() {
	let num = 0;
	let obj = {
		inc: function() {
			num ++;
			return num;
		}
	}
	return obj;
}
let reault = add();
console.log(reault.inc()); //1
console.log(reault.inc()); //2
console.log(reault.inc()); //3

闭包有什么作用?

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

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

相关文章

GPT提示词系统学习-第三课-规范化提示让样本走在提示词前

开篇 本教程将为您提供有关不同类型提示的术语及如何描述它们。尽管提示工程中已经有一些方法来形式化术语,但这个领域仍在不断发展,我们在这篇教程中将给到大家展示一种基于QA形式的通用的、标准的提示语写法。 提示的组成部分 以下是在一个提示中经常会出现的一些组成部…

Triton教程 --- 动态批处理

Triton教程 — 动态批处理 Triton 提供了动态批处理功能&#xff0c;将多个请求组合在一起执行同一模型以提供更大的吞吐量。 默认情况下&#xff0c;只有当每个输入在请求中具有相同的形状时&#xff0c;请求才能被动态批处理。 为了在输入形状经常变化的情况下利用动态批处理…

【PCB专题】Allegro 生成钻孔数据方法

生成Drill Symbol 选择Manufacture->NC->Drill Customization... 在Drill Customization中选择Auto generate symbols(防止钻孔未定义图形符号,选择后会自动产生图形符号)。然后在弹出的警告框中选择是(Y)。最后点击OK。 生成Drill Legend 选择Manufacture->NC-&…

什么是OTN——光传送网?

概要 在现代通信网络中&#xff0c;光纤技术已经成为主流&#xff0c;提供了高速、高带宽的数据传输能力。光传送网&#xff08;Optical Transport Network&#xff0c;OTN&#xff09;是一种基于光纤技术的传输网络&#xff0c;用于实现可靠、高效的光纤通信。本文将详细介绍O…

01 React入门、虚拟DOM

总结 一、React 入门 1.1 特点 高性能、声明式、组件化、单向响应的数据流、JSX扩展、灵活 1.2 React初体验 <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewpo…

AIDA64压力测试教程,AIDA64压力测试多长时间,AIDA64压力测试结果怎么看

硬件管理工具AIDA64功能全面专业&#xff0c;操作简便易学&#xff0c;使用AIDA64进行系统稳定性测试逐渐成为更多用户的选择。可能有很多用户对如何使用AIDA64进行系统稳定性测试不太了解&#xff0c;系统稳定性测试也称为压力测试&#xff0c;或者更通俗的烤机测试&#xff0…

SPI协议详细总结附实例图文讲解通信过程(快速掌握)

目录 一、简介二、数据通信过程2.1 通信总过程总结2.2 具体协议规则2.2.1 时钟极性与时钟相位2.2.2 SPI模式2.2.3 图文实例讲解 2.3 SPI协议优缺点总结 三、其他相关链接 一、简介 SPI(Serial Peripheral nterface&#xff0c;串行外设接口) 协议是一种高速高效率、全双工的通…

数据库SQL Server实验报告 之 SQL数据库的安全性(7/8)

实验名称 数据库的安全性实验 注意&#xff1a;原版word在下载资源里面&#xff08;免费下载&#xff09; 实验目的及要求&#xff1a; 使学生加深对数据库安全性和完整性的理解。掌握SQL Server中有关用户、角色及操作权限…

【Android复习笔记】ARouter / Navigation / EventBus

注:本文主要基于过去 Android View 体系的路由学习笔记整理,不包括最新的 Jetpack Compose 路由体系,如您需了解关于 Jetpack Compose 中的导航路由,请参考 Jetpack Compose 中的导航路由 一文。 传统路由方式 // 显性意图 startActivity(new Intent(this, HomeActivity.c…

JavaScript 的性能分析与提升

JavaScript 的性能分析与提升 对于 JavaScript/前端来说&#xff0c;性能的提升主要有两大方面&#xff1a; 页面初始化的优化 这一方面主要涉及到非代码结构上&#xff0c;但是能够提升用户体验感的优化&#xff0c;如&#xff0c;提升用户看到页面的速度、减少用户等待与页面…

一、枚举类型——使用接口来组织枚举

枚举类型无法被继承&#xff0c;这一点可能有时会让人沮丧。想要继承枚举的动机&#xff0c;一部分源自希望扩充原始枚举中的元素&#xff0c;另一部分源自想要使用子类型来创建不同的子分组。 你可以在一个接口内对元素进行分组&#xff0c;然后基于这个接口生成一个枚举&…

Python零基础入门(三)——基本输入与输出

系列文章目录 个人简介&#xff1a;机电专业在读研究生&#xff0c;CSDN内容合伙人&#xff0c;博主个人首页 Python入门专栏&#xff1a;《Python入门》欢迎阅读&#xff0c;一起进步&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; 码字不易&#xff0c;如果觉得文章不…

关于 Vue3 响应式 API 以及 reactive 和 ref 的用法

文章目录 &#x1f4cb;前言&#x1f3af;关于响应式&#x1f3af;reactive 的用法&#x1f3af;ref 的用法&#x1f4dd;最后 &#x1f4cb;前言 这篇文章记录一下 Vue3 响应式的内容&#xff0c;其中还包括了 reactive 和 ref 的用法。响应式是一种允许以声明式的方式去适应…

VMware16虚拟机安装Ubuntu16.04 LTS

VMware14虚拟机安装Ubuntu16.04 LTS 一、基本介绍二、vmware下安装ubuntu系统2.1 下载ubuntu客户端镜像2.2 安装及配置2.2.1 安装2.2.2 配置 三、ubuntu系统使用 回到目录   回到末尾 一、基本介绍 对于ubuntu而言&#xff0c;就是linux操作系统的具体&#xff0c;而linux对…

S7-1200通过外部端子控制V20变频器启停+MODBUS读写频率的具体方法

S7-1200通过外部端子控制启停+MODBUS读写频率的具体方法 本例中是通过S7-1200PLC外部端子的方式控制变频器启停,用Mobus RTU通讯读写变频器频率。 硬件连接: 屏蔽双绞线将V20变频器P+,N-连接到CPU上CB1241 T/RA 和T/RB, T/RB接P+,T/RA接N-。TA和T/RA用短线连上,TB和T/RB用短…

jmeter函数助手

详解JMeter函数和变量 测试人员可以在JMeter的选项菜单中找到函数助手对话框&#xff08;"Function Helper"对话框&#xff09;&#xff0c;如图11-1所示。 图11-1 函数助手&#xff08;Function Helper&#xff09;对话框 使用函数助手&#xff0c;测试人员可以…

【Python】文件操作 ② ( 文件操作 | 读取文件 | read 函数 | readline 函数 | readlines 函数 )

文章目录 一、读取文件1、read 函数2、readline 函数3、readlines 函数 二、代码示例 - 读取文件1、代码示例 - read 函数读取文件 10 字节内容2、代码示例 - read 函数读取文件所有内容3、代码示例 - readline 函数读取文件一行内容4、代码示例 - readlines 函数读取文件所有内…

利用 AI 作图帮助理解知识

一、背景 人类对图形的接受和处理能力高于对文字和数字的处理能力。 如果我们学习某个知识的时候&#xff0c;能够找到配套的图&#xff0c;理解会好很多。 但&#xff0c;并不是所有的知识都有配图。 然而&#xff0c;人工智能的时代已经来临&#xff0c;为什么不尝试用 AI…

Flutter 项目创建、运行及结构分析

目录 开发工具 创建项目 1.New Flutter Project 1.1直接创建新项目 1.2 已有项目创建新项目 2.选择SDK&#xff0c;补充项目资料 3.Demo已生成 3.1 android 目录 3.2 ios目录 3.3 lib目录 3.4 test 目录(可先不管) 4.配置文件 4.1 pubspec.yaml文件 4.2 pubspec.lock 4…

chatgpt赋能python:Python报错重新执行技巧

Python报错重新执行技巧 如果你在使用Python编程时&#xff0c;经常遇到报错的情况&#xff0c;特别是在大量数据处理或者复杂算法实现时&#xff0c;报错更是常态。那么&#xff0c;你是否不知道该如何处理这些报错信息&#xff0c;或者对于重新执行代码有一些不确定的想法&a…