JS闭包+常见面试题

article/2025/11/7 9:46:11

scope作用域 、Closure闭包对象

可以借助chrome调式工具查看闭包对象

在这里插入图片描述
注意:function声明存在变量提升,所以22行已经存在闭包对象了;

闭包产生的条件:

  1. 函数嵌套;
  2. 嵌套的内部函数引用了外部函数的变量才会产生闭包对象(如果fn1内部fn2外部再定义一个var b='111’它不会在Closure里面);
  3. 执行外部函数(导出外部函数);
    执行函数定义(声明)就产生了闭包(不需要调用外部函数)
    ② 闭包其实就是内部函数,它也是包含被引用对象的变量。
    ③ 闭包的数量跟外部函数调用次数有关,而与内部函数的执行次数无关。

在这里插入图片描述

常见的闭包

  1. 函数作为另一个函数的返回值,将外部函数的返回值赋值给一个变量之后再调用

在这里插入图片描述

  1. 将函数作为实参传递给另一个函数调用

在这里插入图片描述
setTimeout内部的第一个参数callback是一个闭包,内部引用了外部函数的变量msg

闭包的作用

  1. 函数再执行完以后,函数内部声明的局部变量依旧存在内存中,未被回收(延长了局部变量的生命周期);
  2. 在函数外部可以直接访问(操作)函数内部的局部变量;暴露内部变量,暴露指定方法(内部函数),使得外部可以使用指定的方法读取或者操作内部变量。
  3. 闭包对象一直存在的原因:
    fn2没有被引用,函数执行完会自动释放;fn3这个变量会自动释放,f指向fn3这个函数对象的地址,函数对象又关联着闭包对象,所以闭包对象不会被回收(有f还引用着它)。

在这里插入图片描述

闭包的生命周期

产生:嵌套内部函数声明完成时就会产生闭包对象
死亡:嵌套内部函数成为垃圾对象(null)

  1. 函数声明式定义内部函数

函数声明式定义内部函数

  1. 函数表达式(匿名函数)定义内部函数

函数表达式定义内部函数

闭包的应用

  • 可以定义JS模块
    具有特定功能的js文件,将所有数据和功能封装在函数内部(私有),只对外暴露一个内部函数或者包含多个内部函数的对象,模块的使用者,只需要通过调用模块中暴露的函数或者对象中的函数,来实现对应的功能。

定义模块:

在这里插入图片描述

使用方法

在这里插入图片描述

另一种定义模块的方法(立即执行函数):

在这里插入图片描述
使用方法:

在这里插入图片描述

再次优化:

在这里插入图片描述

闭包的缺点

  1. 问题:函数执行完后,函数内部的局部变量没有释放,占用内存事件长,容易导致内存泄漏(占用内存没有被及时释放)。
    解决:少用闭包,及时释放内存,用完后赋值为null,让内部函数成为垃圾对象,回收闭包。

在这里插入图片描述

  1. 问题:当需要内存太大,超出剩余内存时,就会内存溢出(页面崩溃直接报错)

在这里插入图片描述

内存泄漏积累的多了就容易导致内存溢出。

常见的内存泄露

    1. 意外的全局变量,没有用var、let、const声明,直接赋值;
    1. 没有及时清理的定时器或回调函数
    1. 闭包

面试题

在这里插入图片描述

所以最终打印The Window

在这里插入图片描述

最终打印My Object

在这里插入图片描述

① a.fun(1) a.fun(2) a.fun(3) 没有产生新的闭包对象(没有新的引用指向闭包对象),一直用的是var=fun(0)产生的闭包对象,闭包内的变量是n,n是第一次传入的0。
② 每一次都返回新的对象,不断产生新的闭包对象,每一次都打印前一次传入的值(这个值是闭包对象里的值)。
③ 先生成c的闭包对象(打印undefined和0),之后一直用c里面的闭包对象,里面存着上一次的传入值1。

//fun(0) 打印undefined
{fun:function(m){return fun(m,0)}
}
//a.fun(1)
function(1){
return fun(1,0)
}fun(1,0){
console.log(0);//0return {fun:function(m){return fun(m,1)}}
}

第一行打印undefined,0,0,0

//fun(0) 打印undefined
{fun:function(m){return fun(m,0)}
}//fun(0).fun(1) ⇒ fun(1,0)
fun(1,0){
console.log(0);//0return {fun:function(m){return fun(m,1)}}
}//fun(0).fun(1).fun(2) ⇒ fun(2,1)
fun(2,1){
console.log(1);//1return {fun:function(m){return fun(m,2)}}
}//fun(0).fun(1).fun(2).fun(3) ⇒ fun(3,2)
fun(3,2){
console.log(2);//2return {fun:function(m){return fun(m,3)}}
}

第二行打印undefined,0,1,2

//fun(0) 打印undefined
{fun:function(m){return fun(m,0)}
}//c = fun(0).fun(1) ⇒ fun(1,0)
fun(1,0){
console.log(0);//0return {fun:function(m){return fun(m,1)}}
}//c.fun(2) ⇒ fun(2,1)
fun(2,1){
console.log(1);//1return {fun:function(m){return fun(m,2)}}
}//c.fun(3) ⇒ fun(3,1)
fun(3,1){
console.log(1);//1return {fun:function(m){return fun(m,3)}}
}

第三行打印undefined,0,1,1

本篇文章为观看B站尚硅谷的视频讲解后的笔记,点击可快速跳转尚硅谷B站视频


http://chatgpt.dhexx.cn/article/Y0rSi9cT.shtml

相关文章

前端面试题汇总(含答案)(JS篇)

主要自用,持续更新,相同类型的题目尽量放在了一起,参考的实在太多了就没有列出,侵权烦请联系删除。提示:自动生成的目录在页面右边---------->>>>>>>>>>>>>>>> Js的…

前端面试题(js篇)

1.解释一下什么是闭包 什么是闭包:函数使用了不属于自己的局部变量(函数套函数,里面函数使用了外面函数定义的变量) 闭包的作用:避免全局污染 闭包的缺点:使用过多会造成内存泄漏(占用的内存释放不掉) 2.…

js 实现页面隐藏、关闭、刷新给出对应的提示

我们在做项目的时候经常会遇到一些需求,比如在某些页面当点击浏览器刷新 或者关闭的时候会有对应的提示,是否离开或者重新加载此网站。比如csdn写文章的时候就有这个弹窗,这功能就是用onbeforeunload实现的。 注意:如果你加载下面…

js面试题大坑——隐式类型转换

1.1 隐式转换介绍 1.2 隐式转换规则 1.3 坑一:字符串连接符与算术运算符隐式转换规则混淆 1.4 坑二:关系运算符:会把其他数据类型转换成number之后再比较关系 1.5 坑三:复杂数据类型在隐式转换时会先转成String&#xff0…

u一点·料:阿里巴巴1688ued体验设计践行之路

U一点料 阿里巴巴1688UED体验设计践行之路 阿里巴巴1688用户体验部著 图书在版编目(CIP)数据 U一点料:阿里巴巴1688UED体验设计践行之路/阿里巴巴1688用户体验部著. —北京:机械工业出版社,2015.8 ISBN 978-7-111-5122…

一段百年征程的有限单群

1832年的某个清晨,革命中的法国见证了重新决斗。 在某个瞬间,某位青年被对手的枪射中腹部。随后去世。在当时狂热的政治斗争中,仅仅有寥寥数人意识到。法国,甚至世界。又失去了还有一个伟大的头脑。 这位青年姓伽罗华,…

权威发布:新一代人工智能发展白皮书(2017)

来源:机器人大讲堂 指导单位、专家顾问及编写人员 顾 问 潘云鹤 中国工程院院士 指导单位 工业和信息化部信息化和软件服务业司 指导委员会 谢少锋 工信部信软司司长 李冠宇 工信部信软司副司长 徐晓兰 中国电子学会副理事长兼秘书长 张宏图 中国电…

《构建之法,邹欣》阅读笔记

前言: 从2018年10月30日开始,阅读由微软工程师邹欣老师撰写的《构建之法》一书,全书共435页,每天阅读15页,在一个月(30天)完成。每天阅读完成后,需要思考当日的阅读要点和一些思考。…

C语言练习——提高篇

新开通了本人的公众号,欢迎关注:燕南路GISer ,专注GIS干货分享,不定期更新。 主要兴趣:GIS、时空数据挖掘、python、机器学习深度学习 CSDN的部分内容会重写再搬迁到公众号,欢迎关注! 目录 汉诺…

一文说透低代码平台/无代码平台

一、低代码/无代码平台是什么 二、低代码/无代码平台是怎么产生的 三、低代码/无代码平台应具备哪些能力 四、主流的低代码/无代码平台有哪些 五、低代码/无代码平台典型应用场景 六、低代码/无代码平台有什么价值 七、低代码/无代码平台有什么优势 八、低代码/无代码平…

代码知识点

JS&基础知识篇: 1、事件流 分为捕获型、冒泡型,addEventListener的第三个参数,为true是捕获型,为false是冒泡型(即默认不写是冒泡型) 常用的事件:click、mouseover(支持冒泡…

「可视化搭建系统」——从设计到架构,探索前端领域技术和业务价值

阿里巴巴集团前端委员会主席 圆心:未来前端的机会在哪里 对前端未来期许有四点:搭建服务, Serverless,智能化,IDE。仔细想想,一个「可视化搭建系统」的想象空间,正能完美命中这些方面。前端的边…

集合类详解

1.List 1.1 ArrayList ArrayList概述 实现List接口的动态数组(大小可变)。默认初始容量10,随着元素增加容量也在不断变化每次添加之前检查是否需要扩容带来数据向新数组的拷贝,若知道数据量可以指定一个初始容量。ArrayList实现…

魔方还原算法(二) 科先巴的二阶段算法

科先巴的二阶段算法 本文来具体介绍一种具体的魔方还原算法——科先巴的二阶段算法,有一部分相关内容在前篇讲述,主要是方向定义那一块儿,没有看的建议先看一下: 二阶段,顾名思义,解决问题分为两步&#…

BUUCTF cmcc_simplerop

cmcc_simplerop 由于网络安全课程需要,从本篇开始记录BUU的做题记录及wp 常规操作,拿到文件先检查,保护开得不多 ida查看,存在明显溢出,并且提示要使用ROP 利用pwndbg得到偏移量为0x20 找到了系统调用int 0x80 整…

BUUCTF | [GXYCTF2019]BabySQli

BUUCTF | [GXYCTF2019]BabySQli 一、必备基础知识 当号被过滤了使用like,rlike绕过 当or被过滤了使用大小写绕过,双写绕过,&&绕过 二、实战化渗透 [GXYCTF2019]BabySQli 因为本道题目的请求方式是POST,直接上手抓包&a…

Cefsharp 与js交互

C# 部分代码 var setting new CefSettings(); setting.CefCommandLineArgs.Add("disable-gpu", "1"); if(!Directory.Exists(Application.StartupPath "\\BrowserCache")) { Directory.…

CefSharp 知道这些就完事了

文章目录 0. 简介1. 安装2. H.264支持3. 加载本地HTML文件4. 多个窗口显示浏览器5. 执行JavaScript代码6. 在JS中调用C#方法 0. 简介 CefSharp,简单来说就是一款.Net编写的浏览器包,方便你在Winform和WPF中内嵌的Chrome浏览器组件。它支持HTML5。 CefSh…

TinyLFU: A Highly Efficient Cache Admission Policy

缓存是计算机科学中可以提高系统性能的最基本、最有效的一种方法之一。当完整的数据不适合全部缓存时,通过将一小部分数据存放到更快、更接近应用程序的内存中来提高性能。缓存可以提高性能的最直观原因在于数据的访问都表现出相当程度的“局部性”。更正式的表征这…

首次接触CefSharp

无疑是我最拿手的开发工作。可是作为一个想成为全能骑士的程序员,当然要能满足各种开发需求。 但是界面这种东西不让我用前端来做心里会很憋屈的。所以在各种需求面前我都会找是否能与HTML混合开发。 我使用过的混合开发平台 C# WebView 追溯到最早我的混合开发还是…