来自:一只有趣的程序猿 | 责编:乐乐

链接:jianshu.com/p/2fa4e8a1eaf9

闭包的定义

闭包是指有权访问另一个函数作用域中的变量的函数。(JS高级程序设计)

看到这红宝书上关于闭包的解释,起初一脸懵逼,读懂之后其实并不难。

要彻底了解闭包,首先必须了解下面的几个概念:

执行环境:每个函数都有自己的执行环境。当执行函数时,函数的环境就会被推入一个环境栈中。而在函数执行后,栈将其环境弹出,把控制权返回给之前的执行环境。

变量对象:每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。当执行函数时,变量对象会变成活动对象。

作用域链:当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所

在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。

执行环境和变量对象的概念容易理解,但是怎么理解作用域链呢。可以参考下图:

理解作用域链

可以看成是同心圆结构,每一层假设是一个函数,上面都拥有与此层函数关联的变量对象;假设当执行到最里面那个函数,那么作用域链可以看做是图中一条由内到外的线,最前端的就是它本身,最后端就是全局执行环境。

那么它有什么用呢,就是当你访问一个变量的时候,就会沿着作用域链一层层往外查找,直到找到为止,如果到了最外层即全局执行环境下还没找到则报错。

闭包的实现

下面通过具体例子来解释:

function a() {var text = '呵呵哒';return function () {console.log(text);}
}
var b = a();
b();

当a()函数被执行后返回了一个匿名函数,这个匿名函数的作用域链上有引用到a()执行环境的活动对象属性text(不知道活动对象是什么的请看上面变量对象的解释)。

a()函数执行完就马上被销毁了,但是这个函数的变量对象仍然被b所引用,所以它的变量对象不会被垃圾回收机制处理掉,而是会留在内存中。这就形成了一个闭包。最后执行b()依然能读取到已经被销毁的a函数的定义的text变量。

我们换个更清晰的例子:

function a() {var i = 0;return function () {console.log(i++);}
}
var b = a();
b();    //0
b();    //1
b();    //2

这个例子三次调用b()会分别输出0、 1、 2,是因为a()的变量对象被return的闭包函数引用着,所以i会一直留在内存中,并只能被闭包函数所访问。这个闭包函数被赋值给了b,所以b()能对i变量进行自增计算。

闭包的作用

什么,你问我闭包有什么用?

好处就是隐藏变量,然后搭起一条沟通的桥,闭包可以间接操作这个隐藏变量;并且让这个变量留在内存中而不会污染到全局变量。

坏处呢消耗内存,如果一直不释放这个闭包就会一直占用着内存。那要怎么释放呢?很简单,和函数一样赋值null就可以了。(b = null)

彻底了解JS中难懂的闭包相关推荐

  1. 解决js中无敌神兽---闭包

    对于闭包,很长一段时间以来都困扰了我,之前写过一篇闭包的文章,后来感觉解释的还是不够好,所以自己还是多查了一点资料,把自己对闭包的理解记录下来,希望大家在前端的路上,不断坚持,总会收货. 好了,现在我 ...

  2. JS中for循环里面的闭包问题的原因及解决办法

    JS中for循环里面的闭包问题的原因及解决办法 参考文章: (1)JS中for循环里面的闭包问题的原因及解决办法 (2)https://www.cnblogs.com/ZinCode/p/555190 ...

  3. js中的类、继承、闭包

    一.js中的类 类:在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称"实例")共有的属性和方法. Javascript是一种基于对象(obje ...

  4. 今天来谈谈面试官最喜欢问JS中的闭包问题吧

    今天来谈谈面试官最喜欢问JS中的闭包问题吧 1.什么是闭包? 闭包是指有权访问另外一个函数作用域中的变量的函数,闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在.闭包就是函数的&qu ...

  5. 离散数学,Js 中闭包的解释和联系

    总共分三部分说明闭包问题: (1)部分  转发自: https://blog.csdn.net/wzwdcld/article/details/44783459,如侵权,请告知删除. 二元关系  设S ...

  6. 详解js中的闭包(closure)以及闭包的使用

    作用域链 我们知道在js中作用域分为全局作用域与局部作用域,作用域链的访问规则为从内到外,也就是说如果当前的作用域中没有该变量或者方法,则会在包含该作用域的外层作用域中,一层一层的向上找,直到wind ...

  7. js中的闭包问题(持续更新)

    闭包,是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 好啦说人话: "我的理解是,闭包就是能够读取其他函数内部变量的函数." ...

  8. 从λ演算到函数式编程聊闭包(1):闭包概念在Java/PHP/JS中形式

    什么是闭包 如果让谷哥找一下"闭包"这个词,会发现网上关于闭包的文章已经不计其数 维基百科上对闭包的解释就很经典: 在计算机科学中,闭包(Closure)是词法闭包(Lexical ...

  9. js最简单的几个特效_高阶函数不会用?教你JS中最实用的几个高阶函数用法

    不废话,先来看下什么是高阶函数 高阶函数 函数可以作为参数传递 函数可以作为返回值输出 函数作为参数传递 回调函数 在ajax异步请求的过程中,回调函数使用的非常频繁 在不确定请求返回的时间时,将ca ...

最新文章

  1. XDU 翼讯账号算法
  2. Centos环境下mysql源码编译安装
  3. Java SE 6 新特性: 编译器 API
  4. Linux netstat查看网络连接信息
  5. access中总计为first_用Access开发生产管理系统
  6. AT4995-[AGC034E] Complete Compress【树形dp】
  7. 微软集成开发者工具到 Visual Studio 中,Web 工具迎来“大换血”?
  8. 2.4变动和最终变量(Volatile and Final Variables)
  9. 查看oracle中的中文所占字节数
  10. VSCode 上竟然也能约会,谈对象了???
  11. vue3 + typescript + echarts后端动态获取数据显示问题总结
  12. php将文字生成图片显示,php生成文字图片效果
  13. 详谈判断点在多边形内的七种方法
  14. Unity Shader - Rendering Mode 渲染模式
  15. ps 如何裁切图片成一定的长宽高比例
  16. 量化思维与常见的量化标
  17. 30岁萌妹子当电工,在抖音做网红,在电商平台当卖家
  18. 服务器查看文件口令,查看服务器序列号命令
  19. ARMv8/GICv3中断路由
  20. SSRF漏洞之常见Bypass篇

热门文章

  1. linux下查看隐藏的文件
  2. 现代制造工程课堂笔记03:第二部分(含易考点与必考点)
  3. 学习笔记(47):Python实战编程-pack布局
  4. tensorflow2 tensorboard可视化使用
  5. vue怎么合并两个视频_【软件分享】视频分割合并软件哪款好用呢?怎么剪切合并视频?...
  6. 通用无线设备对码软件_珞光全新发布国产通用软件无线电平台 :USRP-LW N310!珞光品牌已实现国产替代...
  7. pta龟兔赛跑Java_PTA-龟兔赛跑
  8. Windows10 + WSL (Ubuntu) + Anaconda + vscode 手把手配置python运行环境(含虚拟环境)
  9. FileSystemObject (FSO)对象方法总结及应用
  10. CSS3实现多样的边框效果