闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解。
要理解闭包,肯定是要先了解js的一个重要特性, 回想一下,那就是函数作用域,作用域分全局和局部,由于作用域链的存在,全局变量能在任何地方被访问到,相反,局部变
量只能在局部访问,而无法在全局的作用域中被访问。因为如果你想访问某个局部变量,首先搜索当前作用域中的变量,如果没有,就会继续向上搜索,直到作用域顶端。先看一个
例子:
1 var gl = 3;2 var foo = function(){3 var lo=2;4 }5 foo();6 7 console.log(gl);//38 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 bar7 }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();//210 f2();//311 f2();//4
当我执行第一个f2的时候,a的值是从1变成了2,因为这里内部的匿名函数对f1的变量a有引用,暂时被保存在闭包中,因此没有被js的垃圾回收机制回收掉,所以,当我再一次调用f2的时候,a的值是上一次的值,也就是2,那么此次调用a的值就变成3了,以此类推。
这些知识很基本的闭包基础,其实只要是在写js脚本,无时无刻都在不经意间会用到闭包,而闭包使用不当,会造成内存泄露,除非你强制关闭浏览器,而我们所接触的js代码,
闭包早已是接触很多了,由于时间原因,下次再补充一些关于匿名函数从执行到销毁的闭包特性。
原标题:js闭包之初步理解( JavaScript closure)
关键词:JavaScript