正确理解闭包及闭包使用场景

正确理解闭包及闭包使用场景一 闭包的特性函数嵌套函数函数内部可以引用外部的参数和变量参数和变量不会被垃圾回收机制回收二 闭包的定义及其优缺点定义 闭包是指有权访问另一个函数作用域中的变量的函数 创建闭包的最常见的方式就是在一个函数内创建另一个函数 通过另一个函数访问这个函数的局部变量缺点 闭包的缺点就是常驻内存 会增大内存使用量 使用不当很容易造成内存泄露 存在闭包的原因 内部的函数存在外部作用域的引用就会导致闭包 闭包是 javascript 语言的一大特点 主要应用闭包场合主要是为了 设计私有的方法和变

请添加图片描述

一、闭包的特性

  1. 函数嵌套函数
  2. 函数内部可以引用外部的参数和变量
  3. 参数和变量不会被垃圾回收机制回收

二、闭包的定义及其优缺点

定义:

闭包 是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量

缺点:

闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。

存在闭包的原因:

内部的函数存在外部作用域的引用就会导致闭包。

三、嵌套函数的闭包

function aaa() { var a = 1; return function(){ alert(a++) }; } var fun = aaa(); fun();// 1 执行后 a++,,然后a还在~ fun();// 2 fun = null;//a被回收!! 

闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗。

四、javascript的垃圾回收原理

五、使用闭包的好处

那么使用闭包有什么好处呢?使用闭包的好处是:

  1. 希望一个变量长期驻扎在内存中
  2. 避免全局变量的污染
  3. 私有成员的存在

六、使用闭包的情况

你只需要知道应用的两种情况即可——函数作为返回值,函数作为参数传递。

一、return 函数作为返回值

function fn(){ var max=10; return function bar(x) { if(x> max){ console.log(x) } } } var f1=fn(); f1(15); 

如上代码,bar函数作为返回值,赋值给f1变量。执行f1(15)时,用到了fn作用域下的max变量的值。至于如何跨作用域取值,可以参考上一节。

二、函数作为参数被传递

var max =10, fn = function(x){ if(x > max){ console.log(x); } }; (function (f) { var max =100; f(15); })(fn); 

如上代码中,fn函数作为一个参数被传递进入另一个函数,赋值给f参数。执行f(15)时,max变量的取值是10,而不是100。

讲自由变量跨作用域取值时,曾经强调过:要去创建这个函数的作用域取值,而不是“父作用域”。理解了这一点,以上两端代码中,自由变量如何取值应该比较简单。

三、IIFE(自执行函数)

var n = '林一一'; (function p(){ console.log(n) })() /* 输出 * 林一一 / 

四、循环赋值

for(var i = 0; i<10; i++){ (function(j){ setTimeout(function(){ console.log(j) }, 1000) })(i) } 

因为存在闭包的原因上面能依次输出1~10,闭包形成了10个互不干扰的私有作用域。将外层的自执行函数去掉后就不存在外部作用域的引用了,输出的结果就是连续的 10。为什么会连续输出10,因为 JS 是单线程的遇到异步的代码不会先执行(会入栈),等到同步的代码执行完 i++ 到 10时,异步代码才开始执行此时的 i=10 输出的都是 10。

五、使用回调函数

window.name = '林一一' setTimeout(function timeHandler(){ console.log(window.name); }, 100) 

七、内存泄露问题

由于IE的js对象和DOM对象使用不同的垃圾收集方法,因此闭包在IE中会导致内存泄露问题,也就是无法销毁驻留在内存中的元素

function closure(){ var oDiv = document.getElementById('oDiv');//oDiv用完之后一直驻留在内存中 oDiv.onclick = function () { alert('oDiv.innerHTML');//这里用oDiv导致内存泄露 }; } closure(); //最后应将oDiv解除引用来避免内存泄露 function closure(){ var oDiv = document.getElementById('oDiv'); var test = oDiv.innerHTML; oDiv.onclick = function () { alert(test); }; oDiv = null; } 

八、闭包的销毁

const outerFn = () => { let count = 0; const innerFn = () => { console.log('count', ++count); } return innerFn; } let closure = outerFn(); // 创建第一个闭包 closure(); closure(); closure = outerFn(); // 销毁第一个闭包,创建第二个闭包 closure(); closure(); closure = null; // 销毁闭包 // 输出结果: // count 1 // count 2 // count 1 // count 2 

简单的总结:

  • 关于闭包的销毁
    • 可在模块或应用结束后来进行空赋值处理,进行销毁,比如上面的:closure = null
    • 等待页面被关闭,才会被销毁。
  • 至于为什么会要这么处理才会被销毁呢?具体的话可以网上找一下 javascript 回收机制,有兴趣的童鞋可以去了解了解。

九、新增

十、必刷题

一、for 循环和闭包(号称必刷题)

var data = []; for (var i = 0; i < 3; i++) { data[i] = function () { console.log(i); }; } data[0](); data[1](); data[2]() /* 输出 3 3 3 / 

这里的 i 是全局下的 i,共用一个作用域,当函数被执行的时候这时的 i=3,导致输出的结构都是3。

● 写法1:自执行函数和闭包(使用闭包改善上面的写法达到预期效果)

var data = []; for (var i = 0; i < 3; i++) { (function(j){ setTimeout( data[j] = function () { console.log(j); }, 0) })(i) } data[0](); data[1](); data[2]() 

● 写法2:使用 let

var data = []; for (let i = 0; i < 3; i++) { data[i] = function () { console.log(i); }; } data[0](); data[1](); data[2]() 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/212987.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午6:48
下一篇 2026年3月18日 下午6:49


相关推荐

  • 利用ffmpeg将H264解码为RGB

    利用ffmpeg将H264解码为RGB由于公司买到了一个不提供解码器的设备,我不得已还要做解码的工作。在网上找了一圈,H264解码比较方便的也就是ffmpeg一系列的函数库了,原本设备中也是用这套函数库解码,但厂家不给提供,没办法,只得自己搞了。

    2022年6月23日
    49
  • 快速了解智能CAN转以太网的使用场景

    快速了解智能CAN转以太网的使用场景什么是 CAN 转以太网 在现场如何使用连接

    2026年3月19日
    2
  • JSP动作–JSP有三种凝视方式

    JSP动作–JSP有三种凝视方式

    2021年11月13日
    46
  • linux fstab 远程,linux下fstab文件详解[通俗易懂]

    linux fstab 远程,linux下fstab文件详解[通俗易懂]1./etc/fstab文件介绍/etc/fstab是用来存放文件系统的静态信息的文件。位于/etc/目录下,可以用命令less/etc/fstab来查看,如果要修改的话,则用命令vi/etc/fstab来修改。当系统启动的时候,系统会自动地从这个文件读取信息,并且会自动将此文件中指定的文件系统挂载到指定的目录。2.fstab文件示例以下是CentOS5.Xfstab文件:#LABEL…

    2025年5月31日
    4
  • 高光谱遥感图像处理与信息提取综述

    高光谱遥感图像处理与信息提取综述高光谱遥感图像处理与信息提取综述 nbsp 高光谱遥感是对地观测的重要手段 高光谱图像处理与信息提取技术则是高光谱遥感领域的核心研究内容之一 高光谱图像处理与信息提取技术的研究主要包括数据降维 图像分类 混合像元分解和目标探测等方向 nbsp 高光谱图像处理与信息提取中面临的关键问题 高光谱图像波段多 数据量大 而且混合像元问题较为严重 且同物异谱影响明显 这都是信息提取研究需要解决的关键问题

    2026年3月16日
    4
  • C语言中各种类型所占字节_C语言简单数据类型

    C语言中各种类型所占字节_C语言简单数据类型首先必须知道u8,s8等数据类型的定义:typedefsignedchars8;typedefunsignedcharu8;typedefsignedshorts16;typedefunsignedshortu16;typedefsignedints32;typedefunsignedintu32;typedef…

    2022年10月15日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号