2024JS闭包完全解析 面试再也无烦恼

news2025/10/27 3:48:20

闭包的由来

JS中的闭包是由于函数作用域和作用域链的特性而产生的。

在JS中,每次定义一个函数时,都会创建一个新的函数作用域。函数内部可以访问函数外部的变量和函数,但是函数外部无法直接访问函数内部的变量和函数。这种作用域的嵌套关系形成了作用域链。

当一个函数内部定义了一个函数,并且内部函数引用了外部函数的变量或函数时,内部函数会持有对外部函数作用域的引用。即使外部函数执行完毕后,这个引用仍然存在于内部函数中,形成了闭包。闭包使得内部函数可以继续访问和操作外部函数的变量,即使外部函数已经不处于活动状态。

闭包的定义

来看看mdn上是怎么说的

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment词法环境)的引用组合。

比如,当一个函数返回另一个函数时,如果被返回的函数引用了其父函数中的变量,那么这个被返回的函数就成为了一个闭包。

//函数作为返回值
function test() {
const a = 11;
return function () {
	return `${a} closure`;
};
}
const t = test();

console.log(t()); //这里就形成了闭包 输出11 closure

// 函数作为参数
function test1(fn) {
const b = 33;
fn();
}
const b = 22;

function fn() {

console.log(`${b} closure`);

}

test1(fn);// 22 closure
//`fn`函数在定义时引用了外部的变量`b`。当`test1`函数调用`fn`函数时,`fn`函数仍然可以访问并使用定义时所引用的外部变量`b`。因此,`fn`函数形成了闭包。

由例子也可以看出,闭包会随着函数的创建而被同时创建。

闭包两个特点
  1. 函数嵌套函数
  2. 内层函数可以访问外层函数的变量和参数,包括可以访问其定义时所处作用域以及父作用域变量
闭包两个作用
  1. 防止变量和参数被垃圾回收机制(变量持久化)
  2. 防止变量和参数被外部污染(变量只在闭包内部可访问)

闭包风险

  1. 可能有内存泄露的风险

⭐⭐️⭐️⭐⭐️️️相关面试回答

(1) 闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment词法环境)的引用组合,包括可以访问其定义时所处作用域以及父作用域中的变量。

(2) 闭包一般是函数嵌套,一个函数返回另外一个函数,内部函数访问外部函数的变量就形成了一个闭包
(3) 闭包的优点是可以私有化变量,将变量私有化到函数内部,并在私有化的基础上进行数据保持
(4) 闭包的缺点是容易造成内存泄露,因为闭包创建的变量会一直存在内存中,需要及时置空,否则会造成内存泄露,影响程序性能

举例作用

(5) 闭包在防抖节流函数柯里化,都应用里数据保持(变量持久化)这个特性
比如在防抖函数中,第一次点击的时候,我们会let一个time一个定时器,如果不采用闭包的话,下次触发函数会重新创建一个新的定时器,两个定时器的引用不同,是没有关联的,使用闭包可以直KKKK接在内存中找到之前创建的计时器,调用就可以直接拿到对应的定时器的时间

闭包经典问题

var arr = [];
for (var i = 0; i < 3; i++) {
  (function(i) {
    arr[i] = function() {
   console.log(i);
    };
  })(i);
}
arr[0]();//1
arr[1]();//2
arr[2]();//3
var res1 = [];
for (let i = 0; i < 3; i++) {
res1[i] = function () {
console.log(i);
};
}
res1[0]();//1
res1[1]();//2
res1[2]();//3

解决问题可以使用立即执行函数来创建一个独立作用域,让每个函数都能捕获到对应的 i 的值。或者用let创建块级作用域

面试题解析

function foo(n, o) {
console.log(o); //第一次undefined
return {
fun: function (m) {
return foo(m, n); // 1, n根据作用域链往上找 n = 0
},
};
}
var a = foo(0); //undefined
a.fun(1); //0
a.fun(2); //0
a.fun(3); //0

第二个

function foo(n, o) {

console.log(o); //undefined // 0 // 1 // 2 // 3

return {

fun: function (m) {

return foo(m, n); //上级作用域的参数一直在改变 //(1,0) // (2,1) //(3,2)

},

};

}
var a = foo(0).fun(1).fun(2).fun(3); //undefined 0 1 2

第三个自己做一下吧


function foo(n, o) {

console.log(o);

return {

fun: function (m) {

return foo(m, n); 

},
};
}

文章到这里就结束了,希望对你有所帮助。

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

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

相关文章

JavaScript中null和undefined的区别

JavaScript中null和undefined是两个特殊的值&#xff0c;经常在编程中遇到。虽然它们经常被混淆&#xff0c;但它们有着不同的含义和用法。本文将详细介绍JavaScript中null和undefined的区别&#xff0c;帮助开发者更好地理解和使用它们。 首先&#xff0c;让我们来了解一下nu…

React入门到精通:掌握前端开发的必备技能!

介绍&#xff1a;React是一个由Facebook开发和维护的JavaScript库&#xff0c;用于构建用户界面&#xff0c;特别是用于构建单页应用程序和移动应用程序的用户界面。以下是对React的详细介绍&#xff1a; 虚拟DOM&#xff1a;React通过使用虚拟DOM&#xff08;Document Object …

蓝桥杯第九届电子类单片机组程序设计(模拟题)

目录 蓝桥杯大赛历届真题 一、第九届比赛题 二、代码实现 main.c iic.c iic.h 前言 蓝桥杯的真题可以再官网上查到&#xff0c;链接放下边了&#xff0c;点击即可跳转到官网&#xff1a; 蓝桥杯大赛历届真题 突然发现官网上的题也不全&#xff0c;而且还有一部分是模拟…

BUUCTF misc 专题(47)[SWPU2019]神奇的二维码

下载附件&#xff0c;得到一张二维码图片&#xff0c;并用工具扫描&#xff08;因为图片违规了&#xff0c;所以就不放了哈。工具的话&#xff0c;一般的二维码扫描都可以&#xff09; swpuctf{flag_is_not_here}&#xff0c;&#xff08;刚开始出了点小差错对不住各位师傅&am…

新时代异步 IO 框架:IO_URING 的原理、用法、业界示例分析

文章目录 IO_URING基本介绍常见 I/O 模型IO_URING 原理核心结构工作模式高级特性 用法APIliburing基本流程Demo 业界示例SeaStar / ScyllaDBCEPHRocksDBClickHouse IO_URING 基本介绍 常见 I/O 模型 当前 Linux 的几种 I/O 模型&#xff1a; I/O 模型 同步 I/O 是目前应用最…

AI:130-基于深度学习的室内导航与定位

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

python 基础知识点(蓝桥杯python科目个人复习计划42)

今日复习内容&#xff1a;重新学习一下贪心算法 今天做题的时候&#xff0c;想了半天贪心算法&#xff0c;结果没全想出来&#xff0c;所以菜就多练&#xff0c;重新学一下呗。 贪心算法是一种常见的算法范式&#xff0c;通常用于求解最优化过程。在每一步的选择中&#xff0…

python学习24

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

光芒绽放:妙用“GLAD原则”打造标准的数据可视化图表

光芒绽放&#xff1a;妙用“GLAD原则”打造标准的数据可视化图表 文章目录 光芒绽放&#xff1a;妙用“GLAD原则”打造标准的数据可视化图表前言一、可视化工具有哪些&#xff1f;二、那如何做出正确可视化图表 &#xff1f;GLAD原则1.G原则2.L原则3.A原则4.D原则 三、总结最后…

AliOS编译三方库

文章目录 1、官网教程2、编译NDK2.1 下载ndk2.2 编译环境准备2.3 安装ndk 3 cmake交叉编译3.1 编译工具链3.2 编译三方库 4 自带编译配置文件的交叉编译 1、官网教程 AliOS开发官网链接&#xff1a;AliOS开发者官网 应用开发下NDK开发有相关NDK开发介绍 2、编译NDK 2.1 下载…

优思学院|六西格玛到底有没有用?

有很多人说&#xff0c;我的企业已经是行业的顶峰&#xff0c;不需要做些什么了&#xff0c;更不需要什么六西格玛。如果你这样想就大错特错了。历史上不乏因自满而错失发展机遇&#xff0c;最终被竞争对手超越的案例。 诺基亚&#xff08;Nokia&#xff09;&#xff0c;曾经的…

102.网游逆向分析与插件开发-网络通信封包解析-解读喊话道具数据包并且利用Net发送

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;解读聊天数据包并且利用Net发送 码云地址&#xff08;游戏窗口化助手 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;cc6370dc5ca6b0176aafc…

【web | CTF】BUUCTF [BJDCTF2020]Easy MD5

天命&#xff1a;好像也挺实用的题目&#xff0c;也是比较经典吧 天命&#xff1a;把php的MD5漏洞都玩了一遍 第一关&#xff1a;MD5绕过 先声明一下&#xff1a;这题的MD5是php&#xff0c;不是mysql的MD5&#xff0c;把我搞迷糊了 一进来题目啥也没有&#xff0c;那么就要看…

P1498 南蛮图腾题解

题目 给定一个正整数n&#xff0c;参考输出样例&#xff0c;输出图形。 输入输出格式 输入格式 每个数据输入一个正整数n&#xff0c;表示图腾的大小&#xff08;此大小非彼大小&#xff09; 输出格式 这个大小的图腾 输入输出样例 输入样例 2 输出样例 /\/__\/\ /\…

前端秘法基础式(CSS)(第一卷)

一.认识CSS CSS 指的是层叠样式表&#xff08;Cascading Style Sheets&#xff09;&#xff0c;它是一种用于描述网页外观和布局的语法 CSS 可以定义网页中元素的字体、颜色、大小、位置、背景等样式&#xff0c;使网页具有美观的外观和统 一的风格。 通过将 CSS 样式表与 HTML…

成员方法传参机制

一、成员方法传参机制 1、值传递&#xff1a;形参改变不影响实参 2、地址传递&#xff1a;形参改变影响实参

wordpress外贸成品网站模板

首页大图slider轮播&#xff0c;橙色风格的wordpress外贸网站模板 https://www.zhanyes.com/waimao/6250.html 蓝色经典风格的wordpress外贸建站模板 https://www.zhanyes.com/waimao/6263.html

NetMizer 日志管理系统 多处前台RCE漏洞复现

0x01 产品简介 NetMizer是提供集成应用交付和应用安全解决方案以实现业务智能网络的优秀全球供应商,为全球企业和运营商提供确保关键业务应用的全面可用性、高性能和完善的安全性的解决方案。 0x02 漏洞概述 NetMizer 日志管理系统position.php、hostdelay.php、等接口处存在…

【动态规划初识】不同的二叉搜索树

每日一道算法题之不同二叉搜索树个数 一、题目描述二、思路三、C++代码一、题目描述 题目来源:LeetCode 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 C++程序要求输入输出格式如下: 示例1:…

Gartner指引:四大误区大揭秘,打造高效安全管理体系

安全管理体系是一个复杂的生态系统&#xff0c;定义了企业的关键信息、安全原则、资源和活动&#xff08;见图1&#xff09;。企业机构所构建和运行的安全体系往往难以既对员工实用&#xff0c;又能有效管理快速发展的数字风险。因此&#xff0c;首席信息官&#xff08;CIO&…