atitit.闭包的概念与理解attilax总结v2 qb18.doc
atitit.闭包的概念与理解attilax总结v2 qb18.doc
1.1. 闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。1
2.1. Atitti java预定义函数式接口 闭包的实现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的更多相关文章
- Atitit 代码复用的理解attilax总结
Atitit 代码复用的理解attilax总结 1.1. 继承1 1.1.1. 模式1:原型继承1 1.1.2. 模式2:复制所有属性进行继承 拷贝继承1 1.1.3. 模式3:混合(mix-in)1 ...
- Atitit 图像金字塔原理与概率 attilax的理解总结qb23
Atitit 图像金字塔原理与概率 attilax的理解总结qb23 1.1. 高斯金字塔 ( Gaussianpyramid): 拉普拉斯金字塔 (Laplacianpyramid):1 1.2 ...
- Atitit 作用域的理解attilax总结
Atitit 作用域的理解attilax总结 1.1. 作用域是指对某一变量和方法具有访问权限的代码空间, 1 1.2. 作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突.1 1.3 ...
- Atitit 泛型原理与理解attilax总结
Atitit 泛型原理与理解attilax总结 1. 泛型历史11.1.1. 由来11.2. 为什么需要泛型,类型安全21.3. 7.泛型的好处22. 泛型的机制编辑22.1.1. 机制32.1.2. ...
- Atitit 游戏的原理与概论attilax总结
Atitit 游戏的原理与概论attilax总结 1. 游戏历史2 1.1.1. 盘点PC游戏史上最重要的50款游戏2 1.1.2. 回味人类文明进程 五款经典的历史游戏2 2. 游戏类型(主要分为6 ...
- Atitit.并发编程原理与概论 attilax总结
Atitit.并发编程原理与概论 attilax总结 1. 并发一般涉及如下几个方面:2 2. 线程安全性 ( 2.2 原子性 2.3 加锁机制2 2.1. 线程封闭3.3.1Ad-hoc线程封闭 3 ...
- Atitit ocr识别原理 与概论 attilax总结
Atitit ocr识别原理 与概论 attilax总结 1.1. Ocr的过程与流程1 1.2. OCR不同技术细分略有不同,但大概原理是一样的. 即主要技术过程是:二值化(又叫归一化)----- ...
- Atitit 视频编码与动画原理attilax总结
Atitit 视频编码与动画原理attilax总结 1.1. 第一步:实现有损图像压缩和解压1 1.2. 接着将其量化,所谓量化,就是信号采样的步长,1 1.3. 第二步:实现宏块误差计算2 1.4. ...
- Atitit 网络爬虫与数据采集器的原理与实践attilax著 v2
Atitit 网络爬虫与数据采集器的原理与实践attilax著 v2 1. 数据采集1 1.1. http lib1 1.2. HTML Parsers,1 1.3. 第8章 web爬取199 1 2 ...
随机推荐
- C#版 Winform界面 Socket编程 Client客户端
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 丢手帕问题即约瑟夫问题的PHP解法
问题描述:n个人排成一圈.从某个人开始,依次报数,数到m的人被杀死.下一个人重新从1开始报数,数到m的人被杀死.直到剩下最后一个人. 解决思路:从数学角度去看,每一次报数决定谁去死是一个n.m的求余数 ...
- React 学习,需要注意几点
最近要开始学习 React 框架了,在学习的过程中,个人作为一个新手觉得需要注意的一些问题 小细节有以下几点: 1:在JSX语法当中,如果遇到 HTML 标签(以 < 开头),将用 HTML 规 ...
- mac osx下django-admin.py出现的问题
mac osx 下面用django-admin.py创建项目的时候,没创建成功出现django-admin.py编辑文件,这主要的原因是mac osx下面django-admin.py被重命名为dja ...
- NOIP提高模拟题 混乱的队伍
混乱的奶牛 Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 & ...
- swift-闭包(代码块)
语法 通用的语法 {(parameters) -> return type in statements } e.g let studname = { println("Welcome ...
- 一张图系列——从CreateProcess到main函数的过程
整体过程如下: 需要说明两点: 1.在XP中,新进程主线程的启动,会先执行一个用户态的APC,会执行ntdll!LdrInitializeThunk进行程序执行前的一些列初始化操作.其中很重要任务就是 ...
- IPv6进阶
IPV6报文部分字段介绍 1.没有校验和字段:优点:当TTL减少时,不需要重新处理,相对于IPV4能减少处理的时间:缺点:必须在上层包含校验和2.下一个报文:可指向扩展报文:(大部分节点不处理和查看大 ...
- JDBC驱动自身问题引发的FullGC
公众号HelloJava刊出一篇<MySQL Statement cancellation timer 故障排查分享>,作者的某服务的线上机器报 502(502是 nginx 做后端健康检 ...
- 用SQL语句将数据表中的数据保存为JSON格式
没有找到好的工具,只想到了拼字符串的方式,用 NVARCHAR(MAX) 可能有截断,不推荐使用,方法中使用了 FOR XML PATH('') 实现,有关其使用方法参考这里 表结构: SQL ...