JS中什么是闭包? 您所在的位置:网站首页 闭包函数优缺点 JS中什么是闭包?

JS中什么是闭包?

2023-09-24 20:06| 来源: 网络整理| 查看: 265

写在前面

天空一声巨响,闭包闪亮登场。闭包在JS中是什么重要的,当然也是面试过程中必问的。在这之前我们要弄清楚什么是调用栈?

调用栈

栈,是一种数据结构,那调用栈其实是V8引擎用来管理函数调用关系的一种数据结构,看下面代码:

var a = 2 function add() { var b = 3 return a + b } add()

想要分析V8引擎怎样预编译代码,[这就需要我上篇文章讲到的内容](Javascript从作用域,作用域链到预编译 - 掘金 (juejin.cn)) 我们直接用图展示:

无标题.png

当V8引擎执行JS时,它会维护出一个内存空间,在它的运行内存里面会创建出一个栈。但是栈的空间是有限的。代码

function foo() { foo() } foo()

当V8引擎执行这段代码时,会出现爆栈的情况。但是我们写代码写了很多函数时,这不会出现爆栈的情况,这是因为当一个函数执行完毕后,该函数的执行上下文就会销毁(出栈) 。

闭包

进入主题,那到底什么是闭包?闭包是怎样形成的?有什么优缺点呢?

定义

当通过调用外部函数返回的内部函数后,即使外部函数已经执行结束了,但是内部函数引用了外部函数的变量依然会保存在内存中,我们把这些集合的变量,称为闭包。

有点抽象?我们直接来看代码:

function a() { function b() { var bbb = 234 console.log(aaa); } var aaa = 123 return b } var demo = a()//闭包 demo()

我们来分析一下,函数a运行结果是返回出了函数b,然后在全局下执行函数b,按道理函数a执行结束了,它的执行上下文会出栈,而函数b要打印定义在a函数里面的aaa,应该找不到会出现报错。

但是此时变量aaa形成了闭包,仍保存在内存中,会打印出结果aaa。

上面代码的调用栈图示: 1.png

形成

其实我们从定义就可以得出:当函数A将内部函数B返回出来调用时就形成了闭包。简单来说两个条件:一:函数A将函数B返回出来;二:调用返回出来的函数B。注意:一定要调用返回出来的函数才会形成闭包。

扩展一下:

自执行函数: (function(){})()可以立即执行,不需要调用。

自执行函数可以更好地用来形成闭包,想让函数a与某一个函数形成闭包,就可以在函数a外面套一个自执行函数形成调用。

优点

根据闭包的特点,闭包有以下几个优点:

模块化开放(实现公有变量) 做缓存 可以封装私有化属性 function add() { let name = 'song' let age = 12 function a() { console.log(name); console.log(age); } return a } var res = add() res()

add函数执行完成后出栈,形成了闭包,调用a函数时也可以访问到add中的变量,这就形成了私有化属性name和age。

防止全局变量污染

因为闭包里面的变量都是定义在函数体内的,都在函数作用域里面,属于局部变量。这样不管在全局是否有相同的变量都不会污染到闭包。

缺点

一旦形成闭包,只有在页面关闭后闭包占用的内存才会被回收,所以造成了内存泄漏。

也就是说V8引擎在创建调用栈后总有闭包占有一定的运行空间,这样内存消耗很大,严重可能出现网页卡顿等问题。

所以我们可以在退出函数之前,将不使用的局部变量进行删除

总结

闭包是在开发项目过程中很重要的一种技术,巧妙地利用它的优点可以让我们在开发过程中如鱼得水,我们不仅要学会使用它,而且要用好它。“士不可以不弘毅,任重而道远”,未来的路还很长,大家一起努力。本文可能有些许错误,欢迎大家批评指正。觉得写得不错的话,别忘了点赞收藏哦。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有