1)什么是闭包

函数执行后返回结果是一个内部函数,并被外部变量所引用,如果内部函数持有被执行函数作用域的变量,即形成了闭包。

可以在内部函数访问到外部函数作用域。使用闭包,一可以读取函数中的变量,二可以将函数中的变量存储在内存中,保护变量不被污染。而正因闭包会把函数中的变量值存储在内存中,会对内存有消耗,所以不能滥用闭包,否则会影响网页性能,造成内存泄漏。当不需要使用闭包时,要及时释放内存,可将内层函数对象的变量赋值为null。

2)闭包原理

函数执行分成两个阶段(预编译阶段和执行阶段)。

在预编译阶段,如果发现内部函数使用了外部函数的变量,则会在内存中创建一个“闭包”对象并保存对应变量值,如果已存在“闭包”,则只需要增加对应属性值即可。
执行完后,函数执行上下文会被销毁,函数对“闭包”对象的引用也会被销毁,但其内部函数还持用该“闭包”的引用,所以内部函数可以继续使用“外部函数”中的变量

利用了函数作用域链的特性,一个函数内部定义的函数会将包含外部函数的活动对象添加到它的作用域链中,函数执行完毕,其执行作用域链销毁,但因内部函数的作用域链仍然在引用这个活动对象,所以其活动对象不会被销毁,直到内部函数被烧毁后才被销毁。

3)优点

可以从内部函数访问外部函数的作用域中的变量,且访问到的变量长期驻扎在内存中,可供之后使用 避免变量污染全局
把变量存到独立的作用域,作为私有成员存在

4)缺点

对内存消耗有负面影响。因内部函数保存了对外部变量的引用,导致无法被垃圾回收,增大内存使用量,所以使用不当会导致内存泄漏
对处理速度具有负面影响。闭包的层级决定了引用的外部变量在查找时经过的作用域链长度
可能获取到意外的值(captured value)

4)应用场景 闭包的应用场景非常多,只要用到了函数柯里化的地方就有闭包的身影,比如防抖节流、定时器、惰性处理等

应用场景一: 典型应用是模块封装,在各模块规范出现之前,都是用这样的方式防止变量污染全局。

var Yideng = (function () {// 这样声明为模块私有变量,外界无法直接访问var foo = 0;function Yideng() {}Yideng.prototype.bar = function bar() {return foo;};return Yideng;
}());

应用场景二: 在循环中创建闭包,防止取到意外的值。
如下代码,无论哪个元素触发事件,都会弹出 3。因为函数执行后引用的 i 是同一个,而 i 在循环结束后就是 3

for (var i = 0; i < 3; i++) {document.getElementById('id' + i).onfocus = function() {alert(i);};
}
//可用闭包解决
function makeCallback(num) {return function() {alert(num);};
}
for (var i = 0; i < 3; i++) {document.getElementById('id' + i).onfocus = makeCallback(i);
}

什么是闭包,为什么要用闭包?相关推荐

  1. Go 学习笔记(18)— 函数(04)[闭包定义、闭包修改变量、闭包记忆效应、闭包实现生成器、闭包复制原对象指针]

    1. 闭包定义 Go 语言中闭包是引用了自由变量的函数,被引用的自由变量和函数一同存在,即使已经离开了自由变量的环境也不会被释放或者删除,在闭包中可以继续使用这个自由变量,因此,简单的说: 函数 + ...

  2. Swift--逃逸闭包与非逃逸闭包(Swift3.1)

    逃逸闭包和非逃逸闭包的理解: Swift中的闭包有两种:逃逸闭包和非逃逸闭包.逃逸闭包表示闭包将在函数返回之后执行:而非逃逸闭包则表示在函数返回前,即函数内部执行. 那么我们是否可以理解为:如果闭包作 ...

  3. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | 闭包 parameterTypes 和 maximumNumberOfParameters 成员用法 )

    文章目录 一.闭包类 Closure 简介 二. 闭包 parameterTypes 和 maximumNumberOfParameters 成员用法 三. 完整代码示例 一.闭包类 Closure ...

  4. 【Groovy】闭包 Closure ( 自定义闭包参数 | 自定义单个闭包参数 | 自定义多个闭包参数 | 闭包参数默认值指定 )

    文章目录 一.自定义闭包参数列表 1.定义一个自定义参数的闭包 2.定义多个自定义参数的闭包 3.为闭包参数指定默认值 二.完整代码示例 一.自定义闭包参数列表 如果要向 闭包 中 , 传递多个参数 ...

  5. python的闭包要素_Python的闭包

    我的理解,Python中的闭包和其他语言中的闭包一样,都是在一个函数中返回另一个函数.def out_fun(num): print('------1-----') def in_fun(in_num ...

  6. javascript闭包_JavaScript闭包教程–带有JS闭包示例代码

    javascript闭包 Closures – many of you JavaScript devs have probably heard this term before. When I sta ...

  7. python 闭包_Python中的闭包

    一.什么是闭包 在谈之前,我们先来说说作用域,变量的作用域无非就两种:全局变量和局部变量.函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量.出于种种原因,我们有时候需要获取到函数 ...

  8. python闭包怎么理解_Python 闭包的理解

    Last Updated on 2019年10月15日 Python中的闭包是一个比较模糊的概念,不太好理解,我最近的面试中也被问及,在一个单例模式的实现上,我用装饰器实现单例,然后面试官就问到了我对 ...

  9. 为什么一个程序中变量只能定义一次_什么是闭包?为什么叫闭包?

    <JavaScript ES6 函数式编程入门经典>4.1理解闭包: 简言之,闭包是一个内部函数.那么什么是内部函数呢?它是在另一个函数内部的函数.比如: function outer() ...

  10. php的闭包函数bingto_php的闭包

    闭包是指在创建时封装周围状态的函数,即使闭包所在的环境的不存在了,闭包中封装的状态依然存在. 匿名函数其实就是没有名称的函数,匿名函数可以赋值给变量,还能像其他任何PHP函数对象那样传递.不过匿名函数 ...

最新文章

  1. 字节跳动推荐平台技术公开,项亮:底层架构有时比上层算法更重要
  2. node进程管理——pm2
  3. 用vb.net实现拖放功能
  4. 数据库冷备份和热备份
  5. mysql读写分离6_6\MySQL 主从同步 、 MySQL 读写分离 、 MySQL 性能调优
  6. impala里面断言的用法
  7. ROS 可视化(一): 发布PointCloud2点云数据到Rviz
  8. 语音识别的最终目标是真正实现人机交互
  9. 阶段3 1.Mybatis_03.自定义Mybatis框架_4.自定义mybatis的编码-解析XML的工具类介绍
  10. 基于SNMP协议的电信网络监测系统的实现
  11. HttpClient 该知道一些概念
  12. 基于51单片机的8位数码管时钟设计—按键修改时间
  13. 小鸡腿U T6 2013FINAL
  14. 从阿里外包到年薪40W+的高级测试工程师,我的2年转行经历...
  15. 我的世界服务器末地文件在哪,我的世界:找不到末地城怎么办?巧用2个操作,就能瞬间找到!...
  16. 大数据 客户标签体系_大数据标签体系建立
  17. Go中的MPG模式解析
  18. 最优化理论基础与方法学习笔记——凸集与凸函数以及手写定理证明
  19. HTML5视频标签 video 的 poster 属性
  20. PTA 7-63 黑白子交换棋局

热门文章

  1. 腾讯广点通开屏广告错误码
  2. 【软考笔记】10. 软件工程
  3. 搭建本地私有的git服务器
  4. Android微信支付集成和踩过的坑
  5. 从阿里云到自建:RocketMQ迁移的注意事项
  6. LFI_to_RCE
  7. Java 修饰符 public/private/protected/不写的区别
  8. HDL—Verilog Language—Vectors—Replication operator
  9. 外汇交易技术——形态分析
  10. MySQL 导入数据的几种方法