作为一个JS的初学者,闭包和作用域感觉一直都很难弄。JavaScript高级程序设计上关于闭包的内容很少,这里参考前人的博客,对于JS中的闭包做一个理解。
什么是闭包
提到闭包之前,我想先说一个作用域的问题。可以移步作用域,
我认为JS很奇妙的一点就是,设定了作用域这么一个玩意,
我们都知道JS中变量分为全局变量和局部变量,局部作用域中可以访问全局作用域中的变量,而全局作用域中则不能访问局部作用域中的变量。举个例子:1
2
3
4
5
6
7
8
9var 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
11var 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 | var fnArr = []; |
这里有两种方法:1
2
3
4
5
6
7
8
9
10var 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
10var fnArr = [];
for (var i = 0; i < 10; i ++) {
(function(){
var n=i;
return fnArr[i] = function(){
return n;
};
})()
}
console.log( fnArr[3]() );
两种方法都是利用自执行函数来创建一个闭包。
参考:阮一峰-JS闭包