关于“闭包”的杂文

本文原文出处: http://blog.csdn.net/bluishglc/article/details/50574039 严禁任何形式的转载,否则将委托CSDN官方维护权益!

定义

关于闭包有太多种解释,但基本上都很难用一两句解释清楚,下面这句简短的定义是我见过的最精炼且准确的解释了:

A closure is a function that carries an implicit binding to all the variables referenced within it. In other words, the function (or method) encloses a context around the things it references.

首先,闭包是一个函数,然后,也是最本质的地方:这个函数内部会引用(依赖)到一些变量,这些变量既不是全局的也不是局部的,而是在定义在上下文中的(这种变量被称为“自由变量”,我们会在稍后的例子中看到这种变量),闭包的“神奇”之处是它可以“cache”或者说是持续的“trace”它所引用的这些变量。(从语言实现层面上解释就是:这些变量以及它们引用的对象不会被GC释放)。同样是这件事情,换另一种说法就是:闭包是一个函数,但同时这个函数“背后”还自带了一个“隐式”的上下文保存了函数内部引用到的一些(自由)变量。

第一个例子

第二个例子

对两个例子的补充

上述两个例子的代码都在解释闭包的概念,但是解释的角度不太一样,相对而言第二个例子揭示地更为深刻一些,它揭示闭包会隐式地持续trace(也就是不会被垃圾回收)它所使用的那些自由变量!

每当我们去调用一个闭包时,脑子里一定要意识到:闭包不单单是定义它的那段代码,同时还有一个绑定在它“后面”(隐式的)的持续保持它所引用的所有自用变量的一个“上下文”(“环境”)!

为什么需要闭包

闭包被创造出来显然是因为有场景需要的。一个最为普遍和典型的使用场合是:推迟执行。我们可以把一段代码封装到闭包里,你可以等到“时机”成熟时去执行它。比如:在Spark里,针对RDD的计算任务都要分布到每个节点(准确的说是executor)上并行处理,Spark就需要封装一个闭包,把相关的操作(方法)和需要的变量引入到闭包中分发给节点执行。

时间: 2024-08-07 21:21:06

关于“闭包”的杂文的相关文章

举例详细说明javascript作用域、闭包原理以及性能问题(转)

这可能是每一个jser都曾经为之头疼的却又非常经典的问题,关系到内存,关系到闭包,关系到javascript运行机制.关系到功能,关系到性能. 文章内容主要参考自<High Performance JavaScript>,这本书对javascript性能方面确实讲的比较深入,大家有空都可以尝试着阅读一下,我这里有中英电子版,需要的话QQ317665171或者QQ邮箱联系. 复习,笔记,更深入的理解. 欢迎拍砖指正. 作用域: 下面我们先搞明白这样几个概念: 函数对象的[[scope]]属性.S

Javascript学习日志(三):闭包

说实话,前面一节的原型和原型链在当初学的时候并没有很头疼,对着高级编程第三版撸了几遍就理解透了,闭包这一节真的挺头疼的,很惭愧,看了差不多十来遍吧,还翻看了网上的其他博客和解释文档,五花八门的表达方式,虽然核心思想都一致,但是实在是不能做到自己的理解,后来结合函数作用域链,好不容易有点开窍,趁着热乎劲儿,赶紧写下来,感兴趣的可以参考一下. 闭包:高级编程上面的解释是指有权访问另一个函数作用域中的变量的函数,(是一个函数): 创建闭包的常见方式,就是在一个函数内部创建另一个函数. 在理解闭包之前,

Python 闭包函数

一.定义: 1. 定义在函数内部的函数 2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用那么该内部函数就称为闭包函数 x=1 def f1(): x=11111111111 def f2(): print(x) return f2 func=f1() 二.闭包函数的应用:惰性计算 def index(url): # url='https://www.python.org' def get(): # return requests.get(url).text print(reques

学习Javascript闭包(Closure)

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于Javascript初学者应该是很有用的. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外

Python 闭包

闭包 1.注意:返回的函数内部不要使用后续会发生变化的变量. def f(): gs = [] for k in range(1, 4): def g(i): return i + k gs.append(g) return gs 例如这段代码感觉上应该返回三个函数分别return i+1.return i+2.return i+3(i为新函数参数),但事实却是得到了三个return i+3. >>> from test import f >>> g1, g2, g3

swift 深入理解Swift的闭包

我们可用swift的闭包来定义变量的值. 先来一个简单的例子大家先感受感受. 定义一个字符串的变量的方法: 直接赋值 var str="JobDeer" 还可以用闭包的方式定义: var str:String={ return "JobDeer" }() 闭包还可以这么定义,省略了等号和括号: var str:String{ return "JobDeer" } 闭包中可以定义get方法. var str:String{ get{ return

浅谈Js闭包现象

一.1.我们探究这个问题的时候如果按照正常的思维顺序,需要知道闭包是什么它是什么意思,但是这样做会让我们很困惑,了解这个问题我们需要知道它的来源,就是我们为什么要使用闭包,先不管它是什么意思!      2.我们使用闭包是因为js的作用域问题,前面我们已经对作用域了解了一些,在函数中,外部不能读取到内部的变量,而内部可以读取到外部的变量,这其实也是js特殊的一个地方!(这个特殊其实是因为函数的作用域是一条作用域链,而且作用域链是有顺序的,我们称之为链式作用域结构!)那么问题来了,如果我们想要从函

js的闭包概念

一.变量的作用域要懂得闭包,起首必须懂得Javascript特别的变量作用域.变量的作用域无非就是两种:全局变量和局部变量.Javascript说话的特别之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999另一方面,在函数外部天然无法读取函数内的局部变量.Js代码 function f1(){ var n=999; } alert(n); // error这里有一个处所须要重视,函数内部声明变量

对js中闭包,作用域,原型的理解

前几天,和朋友聊天,聊到一些js的基础的时候,有一种‘好像知道,好像又不不知道怎么讲的感觉’...于是捡起书,自己理一理,欢迎拍砖. 闭包 理解闭包首先要理解,js垃圾回收机制,也就是当一个函数被执行完后,其作用域会被收回,如果形成了闭包,执行完后其作用域就不会被收回. 如果某个函数被他的父函数之外的一个变量引用,就会形成闭包 闭包的作用,就是保存自己私有的变量,通过提供的接口(方法)给外部使用,但外部不能直接访问该变量. 例子(使用闭包): var test=(function(){ var