概念: 在一个函数外部能够访问该函数内部局部变量的函数, 称为闭包
定义在一个函数内部的函数
只有函数内部的子函数才能读取局部变量
好处: 减少全局空间的污染, 形成命名空间; 一个全局变量只能有一个命名
变量变成局部变量的方法:
3.1 函数内部声明
3.2 通过形参
- function foo(){
- var a = 0;
- function bar(){
- a++;
- console.log(a);
- }
- return bar;
- }
- var demo = foo(); //foo() 返回值为 bar 函数体
- console.log(demo); // a 是闭包变量, 不能被清理掉, 一直存在于内存当中
- demo(); // 打印 1 访问的是局部变量, 并让局部变量的 a 发生了改变
- demo(); // 打印 2 由于上次调用, a 的值已经发生了改变 所以在此执行 a 的值也会发生变化
- // 好处: 减少全局空间的污染
- var QF = (function(){
- var a = 10;
- var b = 20;
- function foo(){
- console.log(a);
- }
- function bar(){
- console.log(b);
- }
- return {
- a,
- b,
- foo,
- bar
- }
- })();
- QF.foo();
- QF.foo();
- QF.bar();
闭包经典的小案例
- // 闭包面试题
- function fun(n,o){
- console.log(o);
- return {
- fun: function(m){
- return fun(m,n);
- }
- };
- }
- var a = fun(0);
- console.log(a) //n = 0;o = undefined
- a.fun(1); // 返回值为 fun(m,n); o = n //m = 1;n = 0
- a.fun(2); //m = 2;n = 0
- a.fun(3); //m = 3;n = 0
- var b = fun(0).fun(1).fun(2).fun(3);
- // fun(0) 刚开始的时候 n 为 0,o 为 undefined
- // fun(0).fun(1) 将 1 的值赋给 m,n 的值为 fun(0) 的时候的 0; 再去执行 fun(n,o), 结果 n 为 1,o 为 0
- // fun(0).fun(1).fun(2) 此时 n 的值为上面的 1, 所以 fun(m,n) = fun(2,1); 再去执行 fun(n,o);n 为 2,o 为 1
- // fun(0).fun(1).fun(2).fun(3) 此时的 n 为 2,m 为 3; 再去执行 fun(m,n) = fun(3,2); 即 fun(n,o);n 为 3,o 为 2
来源: http://www.jianshu.com/p/e15bff47663d