JavaScript闭包从概念、原理到应用

简介: 闭包的概念:有权访问另一个函数作用域中的变量的函数;一般情况就是在一个函数中包含另一个函数。

何为闭包?

闭包的概念:有权访问另一个函数作用域中的变量的函数;一般情况就是在一个函数中包含另一个函数。

从官方定义我们知道闭包是一个函数,只不过这个函数有[特殊权限],可以访问到另一个函数的作用域。

特殊权限?

因为我们知道函数作用域是独立的、封闭的,外部的执行环境是访问不了的,但是闭包具有这个能力和权限。

我们先来看一段普普通通的函数。

网络异常,图片无法展示
|

控制台输出结果:

1
 2
 3

再来看一段局部变量的代码:

网络异常,图片无法展示
|

控制台输出结果:

红色框是当前的这段局部变量代码。看得出,他并没有累加。

网络异常,图片无法展示
|

当我们调用时,局部变量b为0,然后b+=1后返回一个值,然后,此时,因为全局变量不会消失,而局部变量在运行完后,他是会被JavaScript的运行机制处理掉的。

所以,当你调用第二次,他重新创建了变量b,然后,结果可想而知。

//闭包函数
 function add3(){
     var b= 0;
     return function(){
         return b += 1;
     }
 }

最后,就看看我们的特殊权限。

我们将运算过程使用匿名函数包裹,此时,这个匿名函数在我们的主函数内,就相当于时主函数的儿子,既然是父子关系,自然你父亲对待你和对待其他孩子不一样。这就是里面的这个函数的特殊权限。

所以,他是有权限去访问到内部的b的,当我们调用这个函数,因为有子函数的存在,所以b这个对象不会消失。相当于后继有人,b就不会被机制回收。

所以,此时运行结果,也是1、2、3

随后,贴上三段代码,自行琢磨:

//普通函数(全局变量)
 var a = 0;
 function add(){
     return a += 1;
 }
 //调用3次函数
 for (var i = 0; i <3; i++){
     console.log(add());
 }
 //普通函数(局部变量)
 function add2(){
     var b= 0;
     return b += 1;
 }
 //调用3次函数
 for (var i = 0; i <3; i++){
     console.log(add2());
 }
 //闭包函数
 function add3(){
     var b= 0;
     return function(){
         return b += 1;
     }
 }
 //调用请自行琢磨

最终原理

闭包的实现原理,其实是利用了作用域链的特性,我们都知道作用域链就是在当前执行环境下访问某个变量时,如果不存在就一直向外层寻找,最终寻找到最外层也就是全局作用域,这样就形成了一个链条。

至于什么是作用域链,你可以将其看成函数嵌套。

访问某个变量时,如果不存在就一直向外层寻找。

闭包优势

作用1: 隐藏变量,避免全局污染

作用2: 可以读取函数内部的变量

同时闭包使用不当,优点就变成了缺点:

缺点1: 导致变量不会被垃圾回收机制回收,造成内存消耗

缺点2: 不恰当的使用闭包可能会造成内存泄漏的问题

为什么使用闭包时变量不会被垃圾回收机制收销毁呢?

这里需要了解一下JS垃圾回收机制:

JS规定在一个函数作用域内,程序执行完以后变量就会被销毁,这样可节省内存

使用闭包时,按照作用域链的特点,闭包(函数)外面的变量不会被销毁因为函数会一直被调用,所以一直存在,如果闭包使用过多会造成内存销毁

附言

所以说,我们要通晓一个事物的原理,并且最优化的使用它。知己知彼,方可百战百胜。

相关文章
|
1月前
|
JavaScript 前端开发
js 闭包的优点和缺点
【10月更文挑战第27天】JavaScript闭包是一把双刃剑,在合理使用的情况下,它可以带来很多好处,如实现数据封装、记忆功能和模块化等;但如果不注意其缺点,如内存泄漏、变量共享和性能开销等问题,可能会导致代码出现难以调试的错误和性能问题。因此,在使用闭包时,需要谨慎权衡其优缺点,根据具体的应用场景合理地运用闭包。
110 58
|
14天前
|
存储 缓存 JavaScript
如何优化Node.js应用的内存使用以提高性能?
通过以上多种方法的综合运用,可以有效地优化 Node.js 应用的内存使用,提高性能,提升用户体验。同时,不断关注内存管理的最新技术和最佳实践,持续改进应用的性能表现。
|
1月前
|
缓存 JavaScript 前端开发
js 闭包
【10月更文挑战第27天】JavaScript闭包是一种强大的特性,它可以用于实现数据隐藏、记忆和缓存等功能,但在使用时也需要注意内存泄漏和变量共享等问题,以确保代码的质量和性能。
36 7
|
1月前
|
数据可视化 JavaScript 前端开发
数据可视化进阶:D3.js在复杂数据可视化中的应用
【10月更文挑战第26天】数据可视化是将数据以图形、图表等形式呈现的过程,帮助我们理解数据和揭示趋势。D3.js(Data-Driven Documents)是一个基于JavaScript的库,使用HTML、SVG和CSS创建动态、交互式的数据可视化。它通过数据驱动文档的方式,将数据与DOM元素关联,提供高度的灵活性和定制性,适用于复杂数据的可视化任务。 示例代码展示了如何使用D3.js创建一个简单的柱状图,展示了其基本用法。D3.js的链式调用和回调函数机制使代码简洁易懂,支持复杂的布局和交互逻辑。
69 3
|
1月前
|
自然语言处理 JavaScript 前端开发
JavaScript闭包:解锁编程潜能,释放你的创造力
【10月更文挑战第25天】本文深入探讨了JavaScript中的闭包,包括其基本概念、创建方法和实践应用。闭包允许函数访问其定义时的作用域链,常用于数据封装、函数柯里化和模块化编程。文章还提供了闭包的最佳实践,帮助读者更好地理解和使用这一强大特性。
17 2
|
1月前
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
43 0
|
7月前
|
设计模式 JavaScript 前端开发
js开发:请解释闭包(closure)是什么,以及它的用途。
闭包是JavaScript中的关键特性,允许函数访问并操作外部作用域的变量,常用于实现私有变量、模块化和高阶函数。私有变量示例展示了如何创建无法外部访问的计数器;模块化示例演示了封装私有变量和函数,防止全局污染;高阶函数示例则说明了如何使用闭包创建能接收或返回函数的函数。
60 2
|
7月前
|
自然语言处理 JavaScript 前端开发
JavaScript基础知识:什么是闭包(Closure)?
JavaScript基础知识:什么是闭包(Closure)?
58 0
|
7月前
|
JavaScript 前端开发 Java
学习Javascript闭包(Closure)
学习Javascript闭包(Closure)
48 0
|
JavaScript 前端开发 Java
学习Javascript闭包(Closure)
学习Javascript闭包(Closure)