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规定在一个函数作用域内,程序执行完以后变量就会被销毁,这样可节省内存

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

附言

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

相关文章
|
22天前
|
存储 JavaScript 前端开发
解释 JavaScript 中的作用域和作用域链的概念。
【4月更文挑战第4天】JavaScript作用域定义了变量和函数的可见范围,静态决定于编码时。每个函数作为对象拥有`scope`属性,关联运行期上下文集合。执行上下文在函数执行时创建,定义执行环境,每次调用函数都会生成独特上下文。作用域链是按层级组织的作用域集合,自内向外查找变量。变量查找遵循从当前执行上下文到全局上下文的顺序,若找不到则抛出异常。
21 6
|
22天前
|
JavaScript
闭包(js的问题)
闭包(js的问题)
12 0
|
1月前
|
设计模式 JavaScript 前端开发
js开发:请解释闭包(closure)是什么,以及它的用途。
闭包是JavaScript中的关键特性,允许函数访问并操作外部作用域的变量,常用于实现私有变量、模块化和高阶函数。私有变量示例展示了如何创建无法外部访问的计数器;模块化示例演示了封装私有变量和函数,防止全局污染;高阶函数示例则说明了如何使用闭包创建能接收或返回函数的函数。
15 2
|
1月前
|
JavaScript 前端开发 算法
js开发:请解释什么是虚拟DOM(virtual DOM),以及它在React中的应用。
虚拟DOM是React等前端框架的关键技术,它以轻量级JavaScript对象树形式抽象表示实际DOM。当状态改变,React不直接操作DOM,而是先构建新虚拟DOM树。通过高效diff算法比较新旧树,找到最小变更集,仅更新必要部分,提高DOM操作效率,降低性能损耗。虚拟DOM的抽象特性还支持跨平台应用,如React Native。总之,虚拟DOM优化了状态变化时的DOM更新,提升性能和用户体验。
23 0
|
3天前
|
前端开发 JavaScript 编译器
深入解析JavaScript中的异步编程:Promises与async/await的使用与原理
【4月更文挑战第22天】本文深入解析JavaScript异步编程,重点讨论Promises和async/await。Promises用于管理异步操作,有pending、fulfilled和rejected三种状态。通过.then()和.catch()处理结果,但可能导致回调地狱。async/await是ES2017的语法糖,使异步编程更直观,类似同步代码,通过事件循环和微任务队列实现。两者各有优势,适用于不同场景,能有效提升代码可读性和维护性。
|
10天前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
|
29天前
|
JavaScript 前端开发 Java
深入剖析 JavaScript 闭包
深入探讨JavaScript闭包,了解其定义、特性、优缺点及作用。闭包是函数与其引用环境的组合,允许内层函数访问外层作用域,常驻内存可能导致内存泄露。优点包括创建私有变量,缺点则涉及内存使用。闭包在变量搜索中遵循从内到外的规则,并影响变量的作用域和生存周期。理解闭包有助于优化代码并避免性能问题。
21 1
|
30天前
|
开发框架 JavaScript 前端开发
描述JavaScript事件循环机制,并举例说明在游戏循环更新中的应用。
JavaScript的事件循环机制是单线程处理异步操作的关键,由调用栈、事件队列和Web APIs构成。调用栈执行函数,遇到异步操作时交给Web APIs,完成后回调函数进入事件队列。当调用栈空时,事件循环取队列中的任务执行。在游戏开发中,事件循环驱动游戏循环更新,包括输入处理、逻辑更新和渲染。示例代码展示了如何模拟游戏循环,实际开发中常用框架提供更高级别的抽象。
14 1