您的位置:首页 > Web前端 > JavaScript

《你不知道的JavaScript(上卷)》读书总结之闭包

2016-11-27 00:00 176 查看
闭包的“官方”解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。这种文字上的定义确实不好理解,也不知道它说的函数是哪个函数,但如果我们记住了闭包的两种情况,和闭包的作用,或许对闭包会有更好的理解,而不必在意于它的文字定义。

闭包的作用:

①为了突破作用域(对于作用域上篇有介绍),使得我们好像在函数外部也能访问在函数内部定义的局部变量,注意这里用了“好像”一词,因为闭包并不能让我们真正做到在函数外部直接使用函数内部定义的局部变量,但是可以通过某些方法间接使用,而为什么要在函数内部定义变量呢,而不直接在函数外部定义,是为了形成模块,防止变量污染。

function fn1(){
var a=2;
function fn2(){
console.log(a);
}
return fn2;
}
var fn3=fn1();
fn3(); // 2

上面这段代码,使得函数fn2在函数fn1外部得到了执行,是因为在fn1内部有个return,将fn2返回了。

var foo=(function CoolModule(){
var something = "cool";
var another = [1,2,3];
function doSomething(){
console.log(something)
}
function doAnother(){
console.log(another.join("!"))
}
return{
doSomething:doSomething,
doAnother:doAnother
}
})();
foo.doSomething();  // cool
foo.doAnother();    // 1!2!3

这段代码也一样,使得局部变量 doSomething和doAnother这两个函数在外部都得到了执行。这个函数形成模块,只有一个foo变量暴露在全局作用域中。

②为了使得变量一直保存在内存中,不被垃圾回收机制回收。看下面的代码:

function outerFun()
{
var a=0;
function innerFun()
{
a++;
console.log(a);
}
return innerFun;
}
var obj=outerFun();
obj();  // 1
obj();  // 2
var obj2=outerFun();
obj2();  // 1
obj2();  // 2

以上的闭包应用情况中都有一个return,将函数作为返回值,这就是闭包的一种应用情况,还有一种就是将变量作为参数传递。

for(var i=1;i<=5;i++){
setTimeout(function timer(){
console.log(i)
},i*1000)
}

可能你会认为这段代码的输出结果为1-5,但是程序的结果跟我们的预期总是不一样,正确结果为输出五次6,这是因为延迟函数的回调会在循环结束时才执行,所以那时i已经等于6。可以将代码改进如下,结果为1-5。

for(var i=1;i<=5;i++){
(function (j){
setTimeout(function timer(){
console.log(j)
},j*1000)
})(i)
}

这就是闭包的作用和应用情况,至于闭包的第二种用法(本文最后一个代码)与前面所介绍的闭包作用有什么关系我自个也还不是很清楚,可以一起讨论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript