说起闭包这个概念,其实是离散数学中的一种定义,而很程序员们耳熟能详但不一定能说清楚它的含义和用途。本文先简单地介绍下离散数学中的闭包,然后再探讨一下Javascript语言中的闭包是如何创建和应用的。

Closure 闭包

1、闭包的定义

-离散数学

一个关系不具有自反, 对称, 传递这3种基本性质之一,但均可以通过对该关系的扩充(在关系中增添序偶),使扩充后的关系具有这种性质,这种包含该关系的最小扩充称为该关系关于这种性质的闭包.

下面给出闭包的定义:设R是X上的关系,R的自反(或对称,传递)闭包R1是这样的:包含R(或R包含于R1)的自反(或对称,传递)关系,对任意的自反(或对称,传递) 关系S,如果R包含于S,则必有R1包含于S.

满足的条件:
  设R是非空集合A上的关系, R的自反(对称或传递)闭包是A上的关系R' ,满足
  (1) R'是自反的(或对称的,或传递的)
  (2)

 R⊆R'
      (3)对A上任何包含[R的自反(或对称的,或传递的)]关系R" 有R'⊆R"
     
  

   r(R) - R的自反闭包, reflexivity

   s(R) - R的对称闭包, symmetry

   t(R) - R的传递闭包。 transmit


R={<a,b>,<b,a>,<b,c>,<c,d>}

r(R)={<a,a>,<b,b>,<c,c>,<d,d>,<a,b>,<b,a>,<b,c>,<c,d>}

s(R)={<a,b>,<b,a>,<b,c>,<c,b>,<c,d>,<d,c>}

t(R)={<a,b>,<a,b>,<a,c>,<a,d>,<b,c>,<b,d>,<b,a>,<b,b>,<c,d>}

-Javascript

在Javascript高级程序设计中提到:Javascript闭包就是在函数中定义函数,实现的功能就是在函数外部也能访问函数内部的局部变量。

1 var closure = function(){
2     var a = 100;
3     var alertA = function(){
4         return(a);
5     }
6     return alertA;
7 }
8 console.log(closure()());  //100

这个玩意就是闭包,他可以在函数外部访问函数内部的变量,是不是很神奇?

其实没啥神奇的,代码示例中closure()执行了closure这个方法,返回了一个匿名函数,这是一个没有执行的匿名函数,然后通过()函数运算符,执行了closure中的alertA这个方法。alertA返回了私有变量a的值,我们称在子函数中使用父函数的局部变量的结构为闭包结构

2、闭包的应用

-模块化代码

我们再看一个例子

 1 function createFunctions(){
 2     var result = new Array();  3  4 for(var i = 0; i < 10; i++){  5 result[i] = function(num){  6 return function(){  7 return num;  8  }  9  }(i); 10  } 11 return result; 12 } 13 14 var funcs = createFunctions(); 15 for(var i = 0; i < funcs.length; i++){ 16  console.log(funcs[i]()); 17 }

代码示例中createFunctions返回了一个数组,该数组指向多个定义的匿名函数生成的对象,这个闭包可以通过数组不同的索引来调用,相当于一个多元的闭包,在模块化开发时候可以使用这个结构。

3、闭包的缺点

-内存泄露

 1 function assignHandler(){
 2     var element = document.getElementById('someElement');
 3     var id = element.id
 4     element.onclick = function(){
 5         alert(id); // modified -> someElement save as local variable
 6         alert(element.id); //error element is null
 7     }
 8     element = null;  // modified -> release mem invoked by element
 9     return function(){
10         console.log(element); // null
11     }
12 }
13 var m = assignHandler();
14 m();

代码实例中是一个闭包结构,修改部分用//modified ->标注了,未修改前,在IE浏览器中,由于IE的内存回收机制,element.onclick 引用的匿名函数中调用了element.id致使element对象得不到释放,一直存贮在内存中,如果这个函数被调用多次,那么内存中的element引用会越来越多,导致内存泄露。此例是指在引用Html element时候,放在闭包内对象得不到释放而导致的。因此,在使用闭包的同时要注意内存的释放。

4、总结

本文通过几个简单的例子介绍了Javascript的闭包及其应用,实际开发中由于闭包长期内存需要代码释放和比较难理解的语法,所以在没有必要的情况下不建议使用闭包。

5、参考资料

Javascript 高级程序设计第二版

http://cise.sdust.edu.cn/lssx/7StressResolve/cha3/36.htm

转载于:https://www.cnblogs.com/keaixiaoye/p/4184367.html

【Javascript 拾遗之三】Closure 闭包相关推荐

  1. javascript函数作用域与闭包

    8.8. 函数作用域与闭包        如第四章所述,JavaScript函数的函数体在局部作用域中执行,局部作用域不同于全局作用域.本章将解释这些内容和相关的作用域问题,包括闭包.[*] [*] ...

  2. JavaScript从作用域到闭包

    目录 作用域 全局作用域和局部作用域 块作用域与函数作用域 作用域中的声明提前 作用域链 函数声明与赋值 声明式函数.赋值式函数与匿名函数 代码块 自执行函数 闭包  作用域(scope) 全局作用域 ...

  3. Rust Closure 闭包解析(匿名函数)

    Rust Closure 闭包解析(匿名函数) 文章目录 Rust Closure 闭包解析(匿名函数) 正文 1. 简单闭包 - 纯粹的匿名函数 2. 捕获上下文 & FnOnce.FnMu ...

  4. Google公开其JavaScript工具:Closure Compiler

    Google Code官方博客今日开源了一个Google内部使用的JavaScript工具:Closure Compiler.这个工具在Google的Gmail,Google文档和Google地图中都 ...

  5. 【Groovy】闭包 Closure ( 闭包的 delegate 代理策略 | OWNER_FIRST | DELEGATE_FIRST | OWNER_ONLY | DELEGATE_ONLY )

    文章目录 一.闭包的代理策略引入 二.闭包的四种代理策略 一.闭包的代理策略引入 分别在 Groovy 脚本 和 Test 类中定义 fun 方法 , 打印不同的内容 ; 在闭包 Closure 中分 ...

  6. 【Groovy】闭包 Closure ( 闭包中调用 Groovy 脚本中的方法 | owner 与 delegate 区别 | 闭包中调用对象中的方法 )

    文章目录 一.闭包中调用 Groovy 脚本中的方法 二.owner 与 delegate 区别 三.闭包中调用 Groovy 对象中的方法 一.闭包中调用 Groovy 脚本中的方法 在 Groov ...

  7. 【Groovy】闭包 Closure ( 闭包类 Closure 简介 | this、owner、delegate 成员区别 | 静态闭包变量 | 闭包中定义闭包 )

    文章目录 总结 一.静态闭包变量 1.执行普通闭包变量 2.执行静态闭包变量 二. 在闭包中定义闭包 三. 完整代码示例 总结 在闭包中 , 打印 this , owner , delegate , ...

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

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

  9. 【Groovy】闭包 Closure ( 闭包作为函数参数 | 代码示例 )

    文章目录 一.闭包作为函数参数 二.闭包作为函数参数代码示例 一.闭包作为函数参数 声明一个 fun 函数 , 可以 将参数声明为 Closure<?> 闭包类型 , 在该函数中 , 执行 ...

最新文章

  1. 深入学习QWidget-1
  2. UseControls ————用户自定义控件的textbox的传值问题
  3. legend3---PHP使用阿里云短信服务
  4. 如何快速直接从Web of Science下载文献,保存到Endnote
  5. 中断处理及系统调用的处理过程
  6. MySQL的JOIN原理
  7. 《.NET 性能优化》送书活动结果公布
  8. 编写一个程序求输入字符串的长度
  9. 大数据_Flink_数据处理_运行时架构7_程序结构和数据流图---Flink工作笔记0022
  10. paip.为什么软件体积越来越大
  11. rust狗阳的师傅是谁_杨幂迪丽热巴新剧同天官宣,你更期待谁呢?
  12. 王笑京:国家新一代智能交通框架与实施进展
  13. 如何更改xp计算机用户名和密码错误,XP更改开机密码提示“Windows不能更改密码”如何解决...
  14. android 2d mmorpg,20款不可错过,史上最佳的MMORPG游戏(下)
  15. 数据增强:YoloV4当中的Mosaic数据增强方法
  16. Macbook 投影仪连接问题
  17. 快添加用用户并添加指定目录和家目录
  18. mysql中长整型是longint_整型int和长整型long
  19. js字符串基本数据类型
  20. BI神器Power Query(10)-- PQ从文件夹导入数据

热门文章

  1. 怎么看联想计算机的ip,如何查看本机ip
  2. 离散信号的抽取和内插例题_《数字信号处理》学习指导与题解 2011年版
  3. 摩托罗拉为什么要限制自家linux手机,摩托罗拉为何在安卓手机大放异彩的时候,突然开始衰败了呢?...
  4. redis——对项目的一些优化方案
  5. Github(1)-概览,初始化仓库
  6. 《Unity2018入门与实战》笔记(9 / 9):个人总结
  7. oracle添加伪列,Oracle伪列 - jifengtang的个人空间 - OSCHINA - 中文开源技术交流社区...
  8. 三目运算符_C语言知识点:运算符的优先级和结合性
  9. 解决ipfs 出现Error: can‘t publish while offline: pass `--allow-offline` to override的问题
  10. Java集合Stream类