闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解。
要理解闭包,肯定是要先了解js的一个重要特性, 回想一下,那就是函数作用域,作用域分全局和局部,由于作用域链的存在,全局变量能在任何地方被访问到,相反,局部变
量只能在局部访问,而无法在全局的作用域中被访问。因为如果你想访问某个局部变量,首先搜索当前作用域中的变量,如果没有,就会继续向上搜索,直到作用域顶端。先看一个
例子:
1 var gl = 3;
2 var foo = function(){
3 var lo=2;
4 }
5 foo();
6
7 console.log(gl);//3
8 console.log(lo);//lo is not defined
那么,要怎么在外部作用域中拿到局部作用域的变量呢?换句话说,我怎么在全局作用域中,拿到foo中的变量lo呢?
例子:
1 function foo() {
2 var x = 2;
3 function bar() {
4 console.log(x);
5 };
6 }
7 console.log(x);//x is not defined
我想在外部拿到x的值,该怎么做?
首先,在外部作用域中是无法访问到foo函数甚至bar中的变量的,来看,在bar的作用域中,是可以访问foo的作用域中的变量的,因此,我只要在调用foo函数时,将他内部的
bar函数返回出来,结果会怎样呢?改写一下以上代码:
1 function foo() {
2 var x = 2;
3 function bar() {
4 console.log(x);
5 };
6 return bar
7 }
8 var func = foo();
9 func(); //2
这样就拿到了x的值,这就是最简单的闭包。
再来看一个比较常见的闭包应用场景:
1 function f1() {
2 var a = 1;
3 return function() {
4 a++;
5 console.log(a);
6 }
7 }
8 var f2 = f1();
9 f2();//2
10 f2();//3
11 f2();//4
当我执行第一个f2的时候,a的值是从1变成了2,而在f1()调用时赋值给了f2,产生了一个引用,因此,a的值暂时被保存在闭包中或者是f2中,因此没有被js的垃圾回收机制回收掉,所以,当我再一次调用f2的时候,a的值是上一次的值,也就是2,那么此次调用a的值就变成3了,以此类推。
这些知识很基本的闭包基础,其实只要是在写js脚本,无时无刻都在不经意间会用到闭包,而闭包使用不当,会造成内存泄露,除非你强制关闭浏览器。