下面我来从各种刁钻的角度来举例详细阐明,包学包会!看完例子以后再看上面说的目的和实现方式就会有种豁然开朗的感觉了! round 1:
function add() {
var x = 0;
return function () {
return ++x;
}
};
var temp=add();//此处的add()的括号和function add()的括号表达的意思是完全差别的,在此处add体现上面定义的函数,add()体现执行一次上面定义的函数,这一点很关键!
//执行一次的效果就是返回了函数 function () {return ++x;},但是请注意!这里返回的仅仅是函数本身,也就是此时函数尚未执行,故此时x=0
temp();//执行一次返回的函数,++x,此时x=1
console.log(temp());//再次执行一次返回的函数,此时x=2,且输出了函数的返回值2,可以在控制台中看到
这就完成了闭包了,add函数中的x常驻内存,且我可以在add函数外部通过调用它返回的函数来操作这个x,如果看懂了下面可以不看,如果看了其他帖子有一些其他的异或好比立即执行函数之类的可以看看下面的,你很快就不会迷惑了! round 2:
var temp = function add() {
var x = 0;
return function () {
return ++x;
}
};//此处temp体现函数add函数本身,但是尚未执行。
var temp1 = temp();//执行temp函数,返回函数 function () {return ++x;},但尚未执行该函数,故x=0
temp1();//执行temp1,此时执行了一次function () {return ++x;},故x=1
console.log(temp1());//再次执行一次function () {return ++x;},此时x=2,且输出到了控制台
这一回合是为下面的立即执行函数做铺垫,下面立即执行函数版本隆重登场!当当当当! round 3:
var temp = (function add() {
var x = 0;
return function () {
return ++x;
}
})();//仔细看,此处为(fucntion add(){})(),此处执行了立即执行函数,也就是说返回给temp的与round2返回的add函数本身差别,而是返回的 function () {return ++x;}
temp();//顺理成章的,这里直接执行temp,就是执行了function () {return ++x;},故x=1
console.log(temp());//同理x=2
颠末上面三个例子的解说想必你已经胸有定见了,但是肯定还是存在迷惑的,好比说round1中var temp=add();,我不把add()的效果赋给temp直接执行行不可?答案是否定的,有一点肯定要认知清晰,函数是对象,这一点至关紧张,否则将会走入误区。下面举例阐明:
这个是round1的改版:
function add() {
var x = 0;
return function () {
return ++x;
}
};
console.log(add()());//输出1
console.log(add()());//输出1
为什么会这样呢?关键点在于函数是对象,上面实验了两次add()(),在这两次中,add()返回的对象是不一样的,以是他们各自再执行add()()就是为各自的局部变量x加1,以是才两次都输出1,如果改一下
function add() {
var x = 0;
return function () {
return ++x;
}
};
var temp1 = add();
var temp2 = add();
console.log(temp1());//输出1
console.log(temp1());//输出2
console.log(temp2());//输出1
console.log(temp2());//输出2
这样是不是就明确了,同理add函数也不能写成下面这种情势:
function add() {
var x = 0;
return (function () {
return ++x;
})()
};
否则返回的只是一个常量而不是一个对象了。希望这篇文章能给跟我一样在探索闭包的小白一点开导,嘿嘿嘿