闭包:基本概念
闭包是可以包含自由(未绑定)变量的代码块;这些变量不是在这个代码块或者任何全局上下文中定义的,而是在定义代码块的环境中定义。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量的存在,相关变量引用没有释放)和为自由变量提供绑定的计算环境(作用域)。在 Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby 和 Python 等语言中都能找到对闭包不同程度的支持。
闭包的价值在于可以作为函数对象 或者匿名函数,对于类型系统而言这就意味着不仅要表示数据还要表示代码。支持闭包的多数语言都将函数作为第一级对象,就是说这些函数可以存储到变量中、作为参数传递给其他函数,最重要的是能够被函数动态地创建和返回。
闭包的本质
集合 <math>S<math> 是闭集当且仅当 <math>Cl(S)=S<math>。特别的,空集的闭包是空集,<math>X<math> 的闭包是 <math>X<math>。集合的交集的闭包总是集合的闭包的交集的子集(不一定是真子集)。有限多个集合的并集的闭包和这些集合的闭包的并集相等;零个集合的并集为空集,所以这个命题包含了前面的空集的闭包的特殊情况。无限多个集合的并集的闭包不一定等于这些集合的闭包的并集,但前者一定是后者的父集
若 <math>A<math> 为包含 <math>S<math> 的 <math>X<math> 的子空间,则 <math>S<math> 在 <math>A<math> 中计算得到的闭包等于 <math>A<math> 和 <math>S<math> 在 <math>X<math> 中计算得到的闭包(<math>Cl_A(S) = A\cap Cl_X(S)<math>)的交集。特别的,<math>S<math> 在 <math>A<math> 中是稠密的,当且仅当 <math>A<math> 是 <math>Cl_X(S)<math> 的子集。
闭包点
对欧几里德空间的子集 S,x 是 S 的闭包点,若所有以 x 为中心的开球都包含 S 的点(这个点也可以是 x)。
这个定义可以推广到度量空间 X 的任意子集 S。具体地说,对具有度量 d 的度量空间 X,x 是 S 的闭包点,若对所有 r > 0,存在 y 属于 S,使得距离 d(x, y) < r(同样的,可以是 x = y)。另一种说法可以是,x 是 S 的闭包点,若距离 d(x, S) := inf{d(x, s) : s 属于 S} = 0(这里 inf 表示下确界)。
这个定义也可以推广到拓扑空间,只需要用邻域替代“开球”。设 S 是拓扑空间 X 的子集,则 x 是 S 的闭包点,若所有 x 邻域都包含 S 的点。注意,这个定义并不要求邻域是开的。
极限点
闭包点的定义非常接近极限点的定义。这两个定义之间的差别非常微小但很重要——在极限点的定义中,点 x 的邻域必须包含和 x 不同的集合的点。
因此,所有极限点都是闭包点,但不是所有的闭包点都是极限点。不是极限点的闭包点就是孤点。也就是说,点 x 是孤点,若它是 S 的元素,且存在 x 的邻域,该邻域中除了 x 没有其他的点属于 S。
对给定的集合 S 和点 x,x 是 S 的闭包点,当且仅当 x 属于 S,或 x 是 S 的极限点。
集合的闭包
集合 S 的闭包是所有 S 的闭包点组成的集合。S 的闭包写作 cl(S),Cl(S) 或 S?。集合的闭包具有如下性质:
cl(S) 是 S 的闭父集。
cl(S) 是所有包含 S 的闭集的交集。
cl(S) 是包含 S 的最小的闭集。
集合 S 是闭集,当且仅当 S = cl(S)。
若 S 是 T 的子集,则 cl(S) 是 cl(T) 的子集。
若 A 是闭集,则 A 包含 S 当且仅当 A 包含 cl(S)。
有时候,上述第二或第三条性质会被作为拓扑闭包的定义。
在第一可数空间(如度量空间)中,cl(S) 是所有点的收敛数列的所有极限。
在Javascript中闭包(Closure)
闭包的两个特点:
1、作为一个函数变量的一个引用 – 当函数返回时,其处于激活状态。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
例1。
<script type=」text/javascript」>
function sayHello2(name) {
var text = 『Hello 『 + name; // local variable
var sayAlert = function() { alert(text); }
return sayAlert;
}
var sy = sayHello2(『never-online』);
sy();
</script>