Closure 闭包
1、闭包的定义
-离散数学
一个关系不具有自反, 对称, 传递这3种基本性质之一,但均可以通过对该关系的扩充(在关系中增添序偶),使扩充后的关系具有这种性质,这种包含该关系的最小扩充称为该关系关于这种性质的闭包.
下面给出闭包的定义:
设R是X上的关系,R的自反(或对称,传递)闭包R1是这样的:包含R(或R包含于R1)的自反(或对称,传递)关系,对任意的自反(或对称,传递) 关系S,如果R包含于S,则必有R1包含于S.
满足的条件:
r(R) - R的自反闭包, reflexivity
s(R) - R的对称闭包, symmetry
t(R) - R的传递闭包。 transmit
R={<a,b>,<b,a>,<b,c>,<c,d>}
r(R)={<a,a>,<b,b>,<c,c>,<d,d>,<a,b>,<b,a>,<b,c>,<c,d>}
s(R)={<a,b>,<b,a>,<b,c>,<c,b>,<c,d>,<d,c>}
t(R)={<a,b>,<a,b>,<a,c>,<a,d>,<b,c>,<b,d>,<b,a>,<b,b>,<c,d>}
-Javascript
在Javascript高级程序设计中提到:Javascript闭包就是在函数中定义函数,实现的功能就是在函数外部也能访问函数内部的局部变量。
1 var closure = function(){ 2 var a = 100; 3 var alertA = function(){ 4 return(a); 5 } 6 return alertA; 7 } 8 console.log(closure()()); //100
这个玩意就是闭包,他可以在函数外部访问函数内部的变量,是不是很神奇?
其实没啥神奇的,代码示例中closure()执行了closure这个方法,返回了一个匿名函数,这是一个没有执行的匿名函数,然后通过()函数运算符,执行了closure中的alertA这个方法。alertA返回了私有变量a的值,我们称在子函数中使用父函数的局部变量的结构为闭包结构。
2、闭包的应用
-模块化代码
我们再看一个例子
1 function createFunctions(){
2 var result = new Array(); 3 4 for(var i = 0; i < 10; i++){ 5 result[i] = function(num){ 6 return function(){ 7 return num; 8 } 9 }(i); 10 } 11 return result; 12 } 13 14 var funcs = createFunctions(); 15 for(var i = 0; i < funcs.length; i++){ 16 console.log(funcs[i]()); 17 }
代码示例中createFunctions返回了一个数组,该数组指向多个定义的匿名函数生成的对象,这个闭包可以通过数组不同的索引来调用,相当于一个多元的闭包,在模块化开发时候可以使用这个结构。
3、闭包的缺点
-内存泄露
1 function assignHandler(){ 2 var element = document.getElementById('someElement'); 3 var id = element.id 4 element.onclick = function(){ 5 alert(id); // modified -> someElement save as local variable 6 alert(element.id); //error element is null 7 } 8 element = null; // modified -> release mem invoked by element 9 return function(){ 10 console.log(element); // null 11 } 12 } 13 var m = assignHandler(); 14 m();
代码实例中是一个闭包结构,修改部分用//modified ->标注了,未修改前,在IE浏览器中,由于IE的内存回收机制,element.onclick 引用的匿名函数中调用了element.id致使element对象得不到释放,一直存贮在内存中,如果这个函数被调用多次,那么内存中的element引用会越来越多,导致内存泄露。此例是指在引用Html element时候,放在闭包内对象得不到释放而导致的。因此,在使用闭包的同时要注意内存的释放。
4、总结
本文通过几个简单的例子介绍了Javascript的闭包及其应用,实际开发中由于闭包长期内存需要代码释放和比较难理解的语法,所以在没有必要的情况下不建议使用闭包。
5、参考资料
Javascript 高级程序设计第二版
http://cise.sdust.edu.cn/lssx/7StressResolve/cha3/36.htm