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. 矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)

    题目链接 题意: 思路: 直接拿别人的图,自己写太麻烦了~ 然后就可以用矩阵快速幂套模板求递推式啦~ 另外: 这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Go ...

  2. Linux内核笔记——内存管理之slab分配器

    内核版本:linux-2.6.11 内存区和内存对象 伙伴系统是linux用于满足对不同大小块内存分配和释放请求的解决方案,它为slab分配器提供页框分配请求的实现. 如果我们需要请求具有连续物理地址 ...

  3. 工厂模式模拟Spring的bean加载过程

    一.前言    在日常的开发过程,经常使用或碰到的设计模式有代理.工厂.单例.反射模式等等.下面就对工厂模式模拟spring的bean加载过程进行解析,如果对工厂模式不熟悉的,具体可以先去学习一下工厂 ...

  4. BZOJ4455: [Zjoi2016]小星星

    Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这 ...

  5. java中内存分配策略及堆和栈的比较

    Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...

  6. linux install mysql

    sudo apt-get install mysql-server #此处会输入root的密码,设置的密码要记住 sudo apt-get install mysql-client sudo apt- ...

  7. JAVA中使用DOM解析XML文件

    XML是一种方便快捷高效的数据保存传输的格式,在JSON广泛使用之前,XML是服务器和客户端之间数据传输的主要方式.因此,需要使用各种方式,解析服务器传送过来的信息,以供使用者查看. JAVA作为一种 ...

  8. 一台linux真实机实现多台Tomcat服务

    一.事前准备 ü 确保linux并未安装tomcat (这里虚拟机测试) ü 下载jdk与tomcat ① jdk-6u18-ea-bin-b01-linux-i586-20_aug_2009.bin ...

  9. Java 8 forEach简单例子

    1. forEach and Map 1.1 通常这样遍历一个Map Map<String, Integer> items = new HashMap<>(); items.p ...

  10. C++基础_总结

    (1)多态性都有哪些?(静态和动态,然后分别叙述了一下虚函数和函数重载) 多态分为两种:静态和动态.静态主要包括函数重载和模板:动态主要是依靠虚函数实现的. 静态联编:重载函数不加virtual关键字 ...