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:[email protected]

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

Atiend

时间: 2024-10-10 12:33:17

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

作用域、闭包等概念的理解

总结一下我对JS中这些基本却略纠结的概念的理解. 作用域 我们知道,JS不支持块级作用域,只支持函数作用域.函数体内,既不是局部变量,也不是参数的变量称为自由变量.如果没搞清楚函数的作用域,有时某些自由变量的值会与你所想的很不一样.举个简单例子 1 var a = 10; 2 3 function getA() { 4 alert(a); 5 } 6 7 (function() { 8 var a = 20; 9 getA(); //10 10 })(); 11 12 (function(fn)

作用域、原型链、闭包等概念理解

1.执行环境及作用域 (1).执行环境: 定义了变量或函数有权访问的其它数据,决定了它们的各自行为.每个执行环境都有一个与之关联的变量对象(variable object, VO),执行环境中定义的所有变量和函数都会保存在这个对象中,解析器在处理数据的时候就会访问这个内部对象. 全局执行环境是最外层的一个执行环境,在web浏览器中全局执行环境是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的.每个函数都有自己的执行环境,当执行流进入一个函数的时候,函数的环境会被

深入理解Lua的闭包:概念和应用

本文首先通过具体的例子讲解了Lua中闭包的概念,然后总结了闭包的应用场合,最后探讨了Lua中闭包的实现原理. 闭包的概念 在Lua中,闭包(closure)是由一个函数和该函数会访问到的非局部变量(或者是upvalue)组成的,其中非局部变量(non-local variable)是指不是在局部作用范围内定义的一个变量,但同时又不是一个全局变量,主要应用在嵌套函数和匿名函数里,因此若一个闭包没有会访问的非局部变量,那么它就是通常说的函数.也就是说,在Lua中,函数是闭包一种特殊情况.另外在Lua

Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php

Atitit.软件开发概念(11)--网络子系统--url编码 空格问题URLEncoder java js php 1. RFC2396标准 including HTML 4.01 section 17.13.4, and also RFC 1866 (which is supercededby the W3C HTML recommendations). 在form的ContextType是[x-www-form-urlencoded]的时候会对form中的键/值对进行编码,空格被转义成+,

由 JavaScript 看闭包的概念

一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

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

Atitit  ocr识别原理 与概论 attilax总结 1.1. Ocr的过程与流程1 1.2. OCR不同技术细分略有不同,但大概原理是一样的. 即主要技术过程是:二值化(又叫归一化)--------行定位----------字符切分----------字库模型比对(取置信度较高字)---------输出2 1.3. Tesseract 图片布局分析 字符分割和识别2 1.1. Ocr的过程与流程 预处理:对包含文字的图像进行处理以便后续进行特征提取.学习.这个过程的主要目的是减少图像中的

JavaScript闭包的概念及用法

1.闭包的概念: 闭包就是能够读取其他函数内部变量的函数. 例如: function f1(){ var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 其中f2函数就是闭包. 由于在Javascript语言中,只有函数内部的子函数才能读取局部变量, 因此可以把闭包简单理解成"定义在一个函数内部的函数". 所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁.2.

atitit.javascript调用java in swt attilax 总结

atitit.javascript调用java in swt attilax 总结 1. BrowserFunction 简介1 1.1. BrowserFunction 可以分为三类: 1 1.2. 事件监听2 2. ati的实现2 2.1. 页面调用2 2.1.1. --------nativeswing的实现2 2.2. java代码2 3. ---code4 4. 参考5 1. BrowserFunction 简介 为了让读者更好的理解后面的内容,在正式介绍之前,需要让读者简单了解一下 

Atitit.软件硕士  博士课程 一览表 attilax 总结

Atitit.软件硕士  博士课程 一览表 attilax 总结 1. Attilax聚焦的领域1 2. 研究生硕士博士课程汇总表1 3. 博士课程3 4. Attilax额外的4 5. 参考4 1. Attilax聚焦的领域 Dsl 语言 ide 类库 框架 数据库 的实现 Debug工具 文本信息的解锁,无损压缩(pdf ,word2html) 图片物体检测与色情图片识别,人脸识别 信息采集,比较,同步工具,信息发布工具 输入法,词库维护工具  翻译机 垃圾文件识别与清理器 快速启动器(at