如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
闭包包含自由(未绑定到特定对象)变量,这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。
“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。
在PHP、Scala、Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等语言中都能找到对闭包不同程度的支持。
集合 S 是闭集当且仅当 Cl(S)=S(这里的cl即closure,闭包)。特别的,空集的闭包是空集,X 的闭包是 X。集合的交集的闭包总是集合的闭包的交集的子集(不一定是真子集)。有限多个集合的并集的闭包和这些集合的闭包的并集相等;
零个集合的并集为空集,所以这个命题包含了前面的空集的闭包的特殊情况。无限多个集合的并集的闭包不一定等于这些集合的闭包的并集,但前者一定是后者的父集。
@microroom 回答得很正确,我补充一点就是n的作用域问题。AddUpper函数每次被调用,系统都会分配一块新的内存给n变量,在AddUpper函数返回的函数引用消失前,该n变量都不会被释放。在该内部函数中,n可以当做全局变量看待(n不是全局变量),同一个内部函数引用到的是同一个n变量。我的理解:将一个运行环境中本该释放的资源,暴露给其他函数,以使得其能不被释放继续被访问的语言特性。下面举两个例子,至于限制,感觉不要出现一直无法释放的内存就可以吧
//类的构造函数中使用function ClassConstructor(){
//
var a = 1
var func = function(){
console.log('this is a private function')
}
//暴露出本该释放的a和func
return {
a: a,
func: func
}
}
//调用
var handle = new ClassConstructor()
console.log(handle.a)
handle.func()
//保存当前函数的调用者
var caller = {
handler : function (){
this.x = 100
this.y = 200
//假如现在有一个对象,需要为他定义回调用函数,并且此函数需要使用当前对象
var o = this
C.on('event',function(){
//肯定会马上想到this,但是this已经不是caller了,这时候就要闭包
console.log(o.x + o.y)
})
}
}