以下内容属个人理解,如有看不明白或漏洞之处,纯属水平不佳,还望见谅。

关于闭包,高程里的定义是:指有权访问另一个函数作用域中的变量的函数。创建闭包最常见的方法就是在一个函数的内部再创建一个函数。

这里先创建一个函数f

function f(v1, v2) {

// 函数表达式

}

并进行调用

let result = f(5, 10)

为了搞懂闭包,首先要明白上面程序整个过程中发生了什么:

1.当调用f()函数的时候,后台创建了一个f()的执行环境与相应的作用域链(这里的作用域链的来源:在创建f()函数的时候,会创建一个预先包含了全局变量对象的作用域链,并

保存在内部的[[Scope]]属性中,当调用f()函数时,会先创建执行环境,然后通过复制[[Scope]]中的作用域链来构建自己的作用域链

2.使用arguments和其他被命名的参数的值来初始化f()的活动对象(这里的活动对象将会被推入作用域的前端,全局变量对象始终位于最后一位,外部函数的活动对象始终位于第二位,外部函数的外部函数的活动对象始终位于第三位...以此类推,在f()函数的作用域链中包含两个变量对象:本地活动对象和全局变量对象(这里还要注意,全局变量对象是始终存在的,而本地活动对象只有在函数调用的时候才存在,同时作用域链中,仅仅是对对象的引用,而非真的包含这些对象)

3.函数调用结束后,执行环境和作用域链被销毁。

明白过程中后,我们再来看何谓闭包

这里创建一个函数f1,并在其内部返回一个匿名函数

function f1 (v1) {

  return functiono (v2, v3) {

    let o1 = v2 * v1

    let o2 = v3 * v1

    return o1 + o2

  }

}

let sum = f1(5)

let result = sum(2, 3)

sum = null // 解除对匿名函数的引用,释放内存

在上述代码执行后,产生的执行环境和作用域链的关系如下图所示

(这里因为手残画图太丑,就用高程里的这张图代替...将createComparisonFunction当作f1就可以,其余变量自行脑部替换)

在 let sum = f1(5)这里,匿名函数从f1中被返回,其作用域链中包含了本地活动对象,f1的活动对象以及全局变量对象,在f1执行完毕后,执行环境被销毁,但其活动对象却不会被销毁,因为在f1返回的匿名函数的作用域链中,依旧保持着对f1活动对象的引用,只有当匿名函数也销毁了以后,才能真正的销毁所有的活动对象。

由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多,我们建议读者只在绝对必要时再考虑使用闭包。虽然像V8 等优化后的JavaScript 引擎会尝试回收被闭包占用的内存,但请大家还是要慎重使用闭包。

最新文章

  1. 虚拟机体验之 KVM 篇
  2. tomcat 9.0配置管理员用户名和密码
  3. Unity 3D
  4. ENode 1.0 - 消息的重试机制的设计思路
  5. 为什么一定要杀掉病毒?---帮一位老师解决MyDocument.exe优盘文件夹图标病毒问题
  6. 必须使用"角色管理工具"安装或配置microsoft.net framework 3.5
  7. sscanf函数和正则表达式
  8. js 函数定义三种方式
  9. MYSQL导入导出.sql文件
  10. 简单的优化处理 By LINQ TO SQL
  11. #Leet Code# Populating Next Right Pointers in Each Node II
  12. 在mysql中修改表名的sql语句
  13. 【Android】读取sdcard卡上的全部图片而且显示,读取的过程有进度条显示
  14. PHP使用array_intersect()函数求数组交集
  15. http协议中:GET/POST/PUT/DELETE/TRACE/OPTIONS/HEAD方法
  16. 【Spring源码深度解析学习系列】容器的基础XmlBeanFactory(二)
  17. Spring项目定时任务
  18. Tomcat 配置文件server.xml详解
  19. 关于Keychain
  20. CentOS 7下Samba服务安装与配置详解

热门文章

  1. 还是端口回流问题 TCP协议解析
  2. 为什么Linux 实例执行 df 和 du 查看磁盘时结果不一致
  3. Leetcode:面试题 04.03. 特定深度节点链表
  4. 将jsp页面转化为图片或pdf(一)(qq:1324981084)
  5. linux中的挂载命令
  6. pikachu-远程代码、命令执行漏洞(RCE)
  7. C# 根据天、周、月汇总统计生成统计报表
  8. JS常见的表单验证,H5自带的验证和正则表达式的验证
  9. 「Flink」配置使用Flink调试WebUI
  10. ELK学习001:Elastic Stack简介