关于闭包,自己理解的_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 关于闭包,自己理解的

关于闭包,自己理解的

 2013/10/17 15:20:44  ququjioulai  程序员俱乐部  我要评论(0)
  • 摘要:其实一直没搞懂闭包啥意思,然后看jquery基础最后有个对闭包的解释,看得半懂不懂的,试试用java解释下有内部函数的外部函数好比是java里的一个class,当然是一个特殊的类,比如不能再class里直接System.out.println(),但是可以在外部函数里alert()内部函数就好比java里的方法jsfunctionouterFn(){functioninnerFn1(){}functioninnerFn2(){}}javapublicclassouterFn
  • 标签:自己 理解
其实一直没搞懂闭包啥意思,然后看jquery基础最后有个对闭包的解释,看得半懂不懂的,试试用java解释下

有内部函数的外部函数好比是java里的一个class,当然是一个特殊的类,比如不能再class里直接System.out.println(),但是可以在外部函数里alert()

内部函数就好比java里的方法

js
function outerFn(){
    function innerFn1(){
    }
    function innerFn2(){
    }
}
java
public class outerFn{
    public void innerFn1(){
    }
    public void innerFn2(){
    }
}


js里要在外部调用内部函数,两种方法,要么全局变量引用,要么外部函数返回

1:全局变量引用
var global=[];
function outerFn(){
    function innerFn1(){
    }
    global.push(innerFn1);
}
执行
outerFn();//虽然是执行外部函数,但是这里类似java里new了个新对象
global[0]();//类似java里调用对象里的方法

2:外部函数返回
function outerFn(){
    function innerFn1(){
    }
    ...
    return {'fn1':innerFn1,'fn2':innerFn2};
}
执行
var global=outerFn();
global.fn1();
global.fn2();


java里调用方法就很简单
outerFn outer=new outerFn()
outer.innerFn1();
outer.innerFn2();


到目前为止都是很正常的,其实这时候闭包已经创建了,书上对闭包的解释是:当内部函数(innerFn1)在定义它的作用域(outerFn)的外部被引用时(global.fn1();),就创建了一个闭包.

但是当外部函数创建了个变量,且由内部函数调用,然后内部函数在外部函数外调用,问题就来了
js
function outerFn(){
    var outerVal=0;
    ...
}

java
public class outerFn{
    private int outerVal=0;
    ...
}

js里outerVal是局部变量,java里outerVal是一个类的全局变量

js
然后内部函数调用
var outerVal=0;
innerFn1(){
    outerVal++;
    alert(outerVal);
}
return {'fn1':innerFn1};
...

var global=outerFn();
global.fn1();//1
global.fn1();//2

java
private int outerVal=0;
public void innerFn1(){
    outerVal++;
    System.out.println(outerVal);
}

outerFn outer=new outerFn()
outer.innerFn1();//1
outer.innerFn1();//2

js中的outerVal如果没被调用就是普通的变量,当执行了方法后这个变量就会被回收

但是如果被内部变量(innerFn1)引用,并且这个内部变量又被外部引用执行(global.fn1())后,outerVal变量就成了一个类似于存在外部函数(outerFn)中独有的全局变量,内存垃圾回收时不知道什么时候innerFn1还会引用,所以一直就不回收outerVal,一直放在内存里,就有点类似java中的static变量了,区别是java的static是程序启动的时候就创建了,这里的伪static变量是当闭包出现的时候才创建的。


简单来说:

外部函数(outerFn)定义内部函数(innerFn1)。
没有闭包。内存正常回收

外部函数(outerFn)定义内部函数(innerFn1),内部函数引用外部函数的变量(outerVal)。
没有闭包。内存正常回收

内部函数(innerFn1)在外部函数以外引用(global.fn1())。
闭包产生。内存正常回收

当内部函数(innerFn1)调用了外部函数(outerFn)的变量(outerVal),并且内部函数在外部函数以外引用(global.fn1())。
闭包产生,并且outerVal变成类似存在于外部函数中的全局变量(java中的static变量),内存不能正常回收。

有错的话请指正。
发表评论
用户名: 匿名