一.到底什么是闭包?
是只要是函数嵌套函数,不管是被嵌套函数是否引用了外部函数的局部变量就是闭包,还是内部函数必须return出去之后才形成闭包?
1.第一个例子
// #1
function outer(a,b){
var c = 999;
function inner(){
console.log(a,b,c);
}
inner(); // 直接调用了内部函数,并没有return出去,这是闭包么?
}
/*----------------------分割线----------------------------*/
// #2
function outer(a,b){
var c = 999;
// 这种情况下,inner没有引用外部outer的变量
function inner(){
var d = 2;
var e = 3;
console.log(d+e);
}
inner(); // 直接调用了内部函数,并没有return出去,这是闭包么?
}
/*----------------------分割线----------------------------*/
// #3
function outer(a,b){
var c = 999;
// 这种情况下,传入的str如果是变量名的话,就会引用outer内的变量
function inner(str){
console.log(eval(str));
}
return inner;
}
var inner = outer(1,2);
inner("a"); // 1
inner("b"); // 2
inner("c"); // 999
如果只要是函数嵌套函数就是闭包的话,那么如果没有return inner出去的话,也就不会出现在外面引用outer函数的局部变量了(#2),那么outer函数执行过后,即使outer内部的局部变量存在于内存中,也没有程序会访问到了,那么,GC会销毁outer内部的局部变量么?但是#3这种情况下,inner虽然没有显式地调用outer的局部函数,但是存在这种可能性,例如
inner("a")
会访问outer的局部函数a
,那么显然这种情况下,GC肯定不会销毁outer。。
哎呀,反正是很迷惑,请各位大牛给个醍醐灌顶的感觉吧???
2.第二个例子
function outer(a,b){
var c = 999;
function inner(){
console.log(a,b,c);
}
return inner; // 把内部函数return出去,就形成了闭包,这点儿我肯定
}
我们通常所说的闭包(之所以说“通常”,是因为从某种意义上来说,js中所有的函数都是闭包 —— 因为函数内部能够访问到外部的变量。但我们只关心下面所说的“闭包”),它的形成有两个要素:
闭包引用外部函数变量对象中的值;
在外部函数的外部调用闭包。
理解闭包的关键在于:外部函数调用之后其变量对象本应该被销毁,但闭包的存在使我们仍然可以访问外部函数的变量对象。
闭包闭包!了解更多