Js中闭包的理解

       作为一个JS的初学者,闭包和作用域感觉一直都很难弄。JavaScript高级程序设计上关于闭包的内容很少,这里参考前人的博客,对于JS中的闭包做一个理解。

什么是闭包

提到闭包之前,我想先说一个作用域的问题。可以移步作用域,
我认为JS很奇妙的一点就是,设定了作用域这么一个玩意,
我们都知道JS中变量分为全局变量和局部变量,局部作用域中可以访问全局作用域中的变量,而全局作用域中则不能访问局部作用域中的变量。举个例子:

1
2
3
4
5
6
7
8
9
var a=1;
function arr(){
var b=a;
console.log(b);//输出1
return b;
}
arr();
console.log(b);//输出undefined。
var b;//这里涉及到变量提升。

上面这个例子中 就能看出在函数arr中,我们新建了一个变量b,把a的值赋给b,因为JS中存在函数作用域,在这个局部作用域中没有找到a,到他的上一层作用域(这里是全局作用域)找到a,并把值赋值给b,然后返回一直b,在控制台中输出b,
因为在全局作用域中b虽然定义了一个b,但是在全局作用域中无法访问局部作用域中的变量。


闭包的作用

这里就不要运用到闭包的方法:
比如这样:

1
2
3
4
5
6
7
8
9
10
11
var a=1;
var func=(function arr(){
return function(){
b=a;
return b;
}
console.log(b);
})();//自执行函数
func();
console.log(b);//输出b的值为1。
var b;

这里就用到了闭包的知识,简单来说闭包就是:

  • 闭包就是在一个函数中创建一个新的函数,使得外界有权访问这个函数作用域中的参数和变量。(相当于使得我们能读取其他函数内部参数的一个函数。)

    闭包的弊端

    因为这个F函数中的一个函数F1被return推送到全局作用域中,使得这个函数再全局中能被调用,而f1的能被执行是建立在F的条件下的。因为F1在全局作用域中,不会再执行结束后销毁,。就导致 F函数也不会被回收。

  • 就好比,一个麻袋里面被我们迁出一个绳子,我们可以顺着绳子去从麻袋里面调用东西。因为绳子拴在着,麻袋也不会跑。

所以闭包的第一个弊端就是:变量无法自动被回收,久而久之造成内存泄漏(不过这点在WEB端不容易体现。主要体现在node端。)

闭包的几个例子

1
2
3
4
5
6
7
8
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
return i;
};
}
console.log( fnArr[3]() );//10
console.log( fnArr[6]() );//10

这里有两种方法:

1
2
3
4
5
6
7
8
9
10
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
var n=i;
return function(){
return n;
}
}();
}
console.log( fnArr[3]() );


第二种

1
2
3
4
5
6
7
8
9
10
var fnArr = [];
for (var i = 0; i < 10; i ++) {
(function(){
var n=i;
return fnArr[i] = function(){
return n;
};
})()
}
console.log( fnArr[3]() );

两种方法都是利用自执行函数来创建一个闭包。

参考:阮一峰-JS闭包