闭包的概念、形式与应用
um i end do10times(addsum)
这两种情况所面临的问题实质是相同的.在这样的语言中,如果按照作用域规则在执行时确定一个函数的引用环境,那么这个引用环境可能和函数定义时不同.要想使这两段程序正常执行,一个简单的办法是在函数定义时捕获当时的引用环境,并与函数代码组合成一个整体.当把这个整体当作函数调用时,先把其中的引用环境覆盖到当前的引用环境上,然后执行具体代码,并在调用结束后恢复原来的引用环境.这样就保证了函数定义和执行时的引用环境是相同的.这种由引用环境与函数代码组成的实体就是闭包.当然如果编译器或解释器能够确定一个函数在定义和运行时的引用环境是相同的(注 3),那就没有必要把引用环境和代码组合起来了,这时只需要传递普通的函数就可以了.现在可以得出这样的结论:闭包不是函数,只是行为和函数相似,不是所有被传递的函数都需要转化为闭包,只有引用环境可能发生变化的函数才需要这样做.
再次观察上面两个例子会发现,代码中并没有通过名字来调用函数 inc_count 和 addsum,他们根本不需要名字.以第一段代码为例,它可以重写成下面这样:
清单 3. 闭包示例3 function make_counter() return function() c1 = make_counter() print(c1())
上面简单地介绍了闭包的原理,更多的闭包相关的概念和理论请参考参考资源中的"名字,作用域和约束"一章. 一个编程语言需要哪些特性来支持闭包呢,下面列出一些比较重要的条件: 函数是一阶值; 借用一个非常好的说法来做个总结(注 4):对象是附有行为的数据,而闭包是附有数据的行为. 闭包的表现形式 虽然建立在相似的思想之上,各种语言所实现的闭包却有着不同的表现形式,下面我们来看一下闭包在一些常用语言中的表现形式. JavaScript 中的闭包 JavaScript(ECMAScript)不是通用编程语言,但却拥有较大的用户群体,而 Ajax 的流行也使更多的人关注 JavaScript.虽然在进行 DOM 操作时容易引发循环引用问题,但 JavaScript 语言本身对闭包的支持还是很好的,下面是一个简单的例子:
function addx(x) { add8 = addx(8); alert(add8(100));
alert(add9(100));
随着 Ruby on Rails 的走红,Ruby 无疑是时下炙手可热的语言之一,Ruby 吸取了很多其他语言的优点,是非常优秀的语言,从这一点来看,很难说清是 Rails 成就了 Ruby 还是 Ruby 成就了 Rails. Ruby 使用 Block 来定义闭包,Block 在 Ruby 中十分重要,几乎到处都可以看到它的 |
||
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |