atitit.闭包的概念与理解attilax总结v2 qb18.doc

1.1. 闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。1

2. #----闭包(Closures)的原理2

2.1. Atitti java预定义函数式接口  闭包的实现5

2.2. Atitit,闭包的原理以及与函数回调的区别5

1.1. 闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。

这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。

所以,一个闭包就是一个“捕获”或“携带”了其被生成的环境中、所属的变量范围内所引用的所有变量的函数。

当我们执行action时,它输出了我们预期的结果。请注意,当我们执行时,原始的“x”此时已经脱离了它当初的变量环境,但它仍然能用。

当你在代码调试器(debugger)里观察“action”时,会发现很有趣的事情。我们可以看到,C#编译器为我们创建了一个Target类,里面封装了x变量:

闭包(和higher order functions)都是非常有用的东西。如果你曾经开发过稍微复杂一点的Javascript程序,你可能就会知道,这个东西可以被当成很多面向对象特征的替代品,就像C#那样。前不久我还在C#里写了一个例子来验证这种想法。

1.1.1. 闭包是因为JS的一些语言特性而形成的,所以在谈它之前我们首先要了解一下的知识点

1.1.1.1.1. 1.执行上下文
1.1.1.1.2. 2.作用域
1.1.1.1.3. 3.垃圾回收机制
1.1.1.1.4. 4.函数嵌套

2. #----闭包(Closures)的原理

在复杂的应用中,我们一定会遇到这类场景。即在函数运行时需要访问函数定义时的上下文数据(注意:一定要区分函数定义时和函数运行时两个不同的时 刻)。特别是在异步编程模型中,函数的定义和运行又分处不同的时间段,那么保持上下文的问题变得更加突出了。因为我们在任务执行一半时把资源交出去没有问 题,但当任务需要再次继续时我们必须还原现场。

在这个例子中,db.query作为一个公共的数据库查询方法,把"id"这个业务数据传入给db.query,交由其保存是不太合适的。但我们可 以稍作抽象,让db.query再支持一个需要保持状态的数据对象传入,当数据查询完毕后可以把这些状态数据原封不动的回传。如下:

Js代码:

function main(){

var id = "1";

var currentState = new Object();

currentState.person_id = id;

db.query("select name from persons where id=" + id, function(name,state){

output("person id:" + state.person_id + ", name:" + name);

},currentState);//注意currentState是db.query的第三个参数

}

main();

记住这种重要的思路,我们再看看是否还能进一步的抽象?可以的,不过接下的动作之前,我们还要了解在JavaScript中一个函数也是一个对象。 一个函数实例fn除了函数体的定义之外,我们仍然可以在这个函数对象实例之本身扩展其他属性,如fn.a=1;受到这个启发我们尝试把需要保持的状态直接 绑定到函数实例上:

Js代码

function main(){

var id = "1";

var currentState = new Object();

currentState.person_id = id;

function onDataLoad(name){

output("person id:" + onDataLoad.state.person_id + ", name:" + name);

}

onDataLoad.state = currentState ;//为函数指定state属性,用于保持状态

db.query("select name from persons where id=" + id, onDataLoad);

}

我们做了什么?生成了currentState对象,然后在函数onDataLoad定义时,将currentState绑定给 onDataLoad这个函数实例。那么在onDataLoad运行时,就可以拿到定义时的state对象了。JavaScript的闭包特性就是内置了 这个过程而已。

在每个JavaScript函数运行时,都有一个运行时内部对象称为Execution Context,它包含如下Variable Object(VO,变量对象), Scope Chain(作用域链)和"this" Value三部分。如图:

图片来自ECMA-262 JavaScript .The Core

其中变量对象VO,包含了所有局部变量的引用。对于main函数,局部变量"id"存储在VO.id内。看起来用VO来代替我们的 currentSate最合适了。但main函数还可能嵌套在其他函数之内,所以我们需要ScopeChain,它是一个包含当前运行函数VO和其所有父 函数scope的数组。

所以在这个例子中,在onDataLoad函数定义时,就为默认为其绑定了一个[[scope]]属性指向其父函数的 ExecutionContext的ScopeChain。而当函数onDataLoad执行时,就可以通过[[scope]]属性来访问父函数的VO对 象来找到id,如果父函数的VO中没有id这个属性,就再继续向上查找其祖先的VO对象,直到找到id这个属性或到达最外层返回undefined。也正 是因为这个引用,造成VO的引用计数不为0,在走出作用域时,才不会被垃圾回收。

很多朋友觉得闭包较难理解,其实我们只要能明确的区分函数定义和函数运行两个时机,那么闭包就是让函数在运行时能够访问到函数定义时的所处作用域内的所有变量,或者说函数定义时能访问到什么变量,那么在函数运行时通过相同的变量名一样能访问到

2.1. 3. 闭包应用的场景

2.1.0.1. 1. 函数作为返回值

2.1.0.2. 2.函数作为参数被传递

2.2. Atitti java预定义函数式接口  闭包的实现

Jdk7使用匿名类与方法实现闭包

2.3. Atitit,闭包的原理以及与函数回调的区别

2.3.1. 闭包对异步编程模型是非常重要的,简单说就是“回调”,你说C的函数指针也是回调的方式,没错,但是参数传递会要了你的命!闭包能够自动“捕获”上下文变量是非常方便的。

现代语言的几个特征,闭包(Closure),运算符重载,自动内存管理这回Swift解决的比Java还完美,闭包自动捕获(Capture)上下文变量,是可以修改变量值的哦(Java印象中是只读捕获)!

参考

闭包.doc  这个可以dep了。。

一波水文来袭-让我们一起谈谈闭包 - 一半水一半冰 - 博客园.html

作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 )

汉字名:艾提拉(艾龙),   EMAIL:1466519819@qq.com

转载请注明来源: http://www.cnblogs.com/attilax/

Atiend

atitit.闭包的概念与理解attilax总结v2 qb18.doc的更多相关文章

  1. Atitit 代码复用的理解attilax总结

    Atitit 代码复用的理解attilax总结 1.1. 继承1 1.1.1. 模式1:原型继承1 1.1.2. 模式2:复制所有属性进行继承 拷贝继承1 1.1.3. 模式3:混合(mix-in)1 ...

  2. Atitit 图像金字塔原理与概率 attilax的理解总结qb23

    Atitit 图像金字塔原理与概率 attilax的理解总结qb23 1.1. 高斯金字塔  (  Gaussianpyramid): 拉普拉斯金字塔 (Laplacianpyramid):1 1.2 ...

  3. Atitit 作用域的理解attilax总结

    Atitit 作用域的理解attilax总结 1.1. 作用域是指对某一变量和方法具有访问权限的代码空间, 1 1.2. 作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突.1 1.3 ...

  4. Atitit 泛型原理与理解attilax总结

    Atitit 泛型原理与理解attilax总结 1. 泛型历史11.1.1. 由来11.2. 为什么需要泛型,类型安全21.3. 7.泛型的好处22. 泛型的机制编辑22.1.1. 机制32.1.2. ...

  5. Atitit 游戏的原理与概论attilax总结

    Atitit 游戏的原理与概论attilax总结 1. 游戏历史2 1.1.1. 盘点PC游戏史上最重要的50款游戏2 1.1.2. 回味人类文明进程 五款经典的历史游戏2 2. 游戏类型(主要分为6 ...

  6. Atitit.并发编程原理与概论 attilax总结

    Atitit.并发编程原理与概论 attilax总结 1. 并发一般涉及如下几个方面:2 2. 线程安全性 ( 2.2 原子性 2.3 加锁机制2 2.1. 线程封闭3.3.1Ad-hoc线程封闭 3 ...

  7. Atitit  ocr识别原理 与概论 attilax总结

    Atitit  ocr识别原理 与概论 attilax总结 1.1. Ocr的过程与流程1 1.2. OCR不同技术细分略有不同,但大概原理是一样的. 即主要技术过程是:二值化(又叫归一化)----- ...

  8. Atitit 视频编码与动画原理attilax总结

    Atitit 视频编码与动画原理attilax总结 1.1. 第一步:实现有损图像压缩和解压1 1.2. 接着将其量化,所谓量化,就是信号采样的步长,1 1.3. 第二步:实现宏块误差计算2 1.4. ...

  9. Atitit 网络爬虫与数据采集器的原理与实践attilax著 v2

    Atitit 网络爬虫与数据采集器的原理与实践attilax著 v2 1. 数据采集1 1.1. http lib1 1.2. HTML Parsers,1 1.3. 第8章 web爬取199 1 2 ...

随机推荐

  1. ListView总结

    ListView类作为在Android开发中经常会使用到的组件,作为新手,还是感到这一块变化形式还是很多的,需要慢慢学习.现在这里大概总结一下. 基于数组的ListView:使用android:ent ...

  2. 设置Flush刷新模式setFlushMode()

    参考 http://blog.csdn.net/superdog007/article/details/38852399 FlushMode的枚举值: FlushMode.ALWAYS:任务一条SQL ...

  3. java-JDBC登录注册代码

    登录: public static void main(String[] args) throws Exception{ Scanner sc = new Scanner(System.in); Sy ...

  4. PMP备考_第六章_项目时间管理

    项目时间管理 前言 项目时间管理是项目管理中最难的一个环节,与个人时间管理类似,团体的效率如果管理不当,是低于个人效率的,为了管理好时间,从预估,执行到反馈均需要严格的分析和处理.如果制定的计划是无法 ...

  5. 赵文豪 GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 使用gdb调 ...

  6. HTML实践发现(标签<pre>)

    1. (1).第一种编辑: (2).浏览器中显示: 2. (1).第二种编辑 (2).浏览器中显示: 结果发现:使用标签<pre>,在浏览器中显示的结果与在<pre>下方编写的 ...

  7. ASP.NET Identity V2

    Microsoft.AspNet.Identity是微软在MVC 5.0中新引入的一种membership框架,和之前ASP.NET传统的membership以及WebPage所带来的SimpleMe ...

  8. Linux堆内存管理深入分析(上)

    Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全   0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞 ...

  9. (翻译)《Hands-on Node.js》—— Introduction

    今天开始会和大熊君{{bb}}一起着手翻译node的系列外文书籍,大熊负责翻译<Node.js IN ACTION>一书,而我暂时负责翻译这本<Hands-on Node.js> ...

  10. 使用 nvm 管理不同版本的 node 与 npm

    补充说明:Mac 下通过 brew install nvm 所安装的 nvm ,由于安装路径不同,无法正确启用.建议使用 brew uninstall nvm 卸载掉之后,通过本文的方案重新安装一次. ...