闭包(Closures) 3 – 图解闭包

说到 闭包 ,这是js不得不提的一个特性,很多传统语言都不具备这样的特性,比如JAVA C等等。

之前看书的时候,总是理解不好什么是闭包!下面就通过手绘一张原理图,来理解一下:

首先基本上所有的编程语言都有类似的特性,局部方法可以访问外部父类方法的属性,也就是说,子类或子方法可以访问父类的资源。

1var num = 11;  
2function func1(){  
3console.log(num);  
4}  
5func1();  

因此上面的这段代码,我们可以获取到num的值。

父类能否获取到子方法内部的值呢?

1function func2(){  
2var num1 = 22;  
3num2 = 33;  
4}  
5func2();  
6<!--console.log(num1); 会报错-->
7  
8console.log(num2); <!--可以获取到num2的值因为不使用var定义变量时默认是全局变量 -->

当然是不可以的,因为子方法的变量作用域仅仅是子方法的范围,外部是无法获取到的。

那么如何才能在外部获取到子方法的局部变量呢!

如果是java,一个类的私有属性,可以通过公共的get方法来获取,比如:

1class Person{  
2private String name;  
3public String getName(){  
4return name;  
5}  
6}  

通过上面的方式可以获取到一个类内部的私有属性,同样的,在js中可以通过某个方法来获取这个方法的局部变量,然后通过这个方法内的方法来读取想要的变量值。

1function func3(){  
2var num3 = 44;  
3function func4(){  
4return num3;  
5}  
6return func4;  
7}  
8var func = func3();  
9console.log(func());  

参考下面的图解:

在外部无法获取到func3内部的局部变量,但是func3内部的局部方法func4却可以获取到,因此 返回一个func4的引用 ,这样在外部通过这个func4就可以获取到func3的内部变量。

虽然是绕了一个圈子,但是在方法外部却通过这样一个手段获取到了内部的值。

而这个方法内的局部方法func4就叫做闭包,按照很多书上的概念,这个方法搭建了方法内部与方法外部的桥梁,使得在外部也可以任意的获取到方法内部的资源。

但是闭包会造成变量在内存中持久占用,因此会有一定的性能问题,最好不要轻易使用,即便使用也要在恰当的实际进行释放。

原文:http://www.cnblogs.com/xing901022/p/4282503.html