闭包?反正看完我就懂了
想要好好的理解闭包,你得首先理解作用域。别说了,赶紧去看作用域吧,😩,这世界就是如此残酷。好,言归正传,我们是来学习闭包的。O(∩_∩)O
什么是闭包??
百度了一波,but理解不了哇。别怕,我来帮你。其实,可以这样理解的:魔术师的幕后藏着一个人,我们要揭开他的伪装,伪装之后的那个人是..知道你会说就是闭包了。闭包就是函数定义时的上下文环境。
get闭包
说了这么久,还不上菜,都快要饿死了。
菜来了!😊
闭包只要记住:
- 闭包产生是:函数内嵌套函数;
- 闭包函数在外面被调用,访问;
- 闭包可以访问外部的变量,但是外部的变量不能访问内部;
- 闭包可以保持对定义时的作用域的引用,使之不被销毁,长生不老。
可能你又懵了,不怕,咱用实例来说话。
实例一:
function foo(){
var a=2;
function bar(){
console.log(a);//2
}
bar();
}
foo();
这看起来应该就是闭包吧,不,确切地说它不是。因为bar()嵌套在foo()内部,这里并没有在外面调用bar().
闭包来啦
var func=function(){
var a=1;
return function(){
a++;
alert(a);
}
}
var f=func();
f();//闭包哇!
函数f()的词法作用域能够访问func()的内部作用域,然后把里面的匿名函数function()本身当作一个值类型进行传递。其实这个闭包的产生过程可以理解为在里面的匿名函数定义时正处于怀孕阶段,到外面f()调用时,娃就出生了,娃就是闭包啦。
不一般的闭包
有时候对函数类型的值进行参数传递有很多种方法,但是不要方,当他们在别处被调用时仍然可以观察到闭包。
看下面:
function foo(){
var a=2;
function baz(){
console.log(a);//2
}
bar(baz);
}
function bar(fn){
fn();//妈,闭包又来啦
}
把内部的函数baz传递给bar,当调用这个内部函数时(现在叫fn()),它涵盖的foo()内部作用域就出来了,因为它能够访问a.
还有这样的闭包
function wait(message){
setTimeout(function timer(){
console.log(message);
},1000);
}
wait("Hello,closure!");
将一个内部函数(名为timer)传递给setTimeout(...)。timer具有涵盖wait(...)作用域的闭包,还保留着对变量message的引用。
循环和闭包
for(var i=1;i<=5;i++){
(function(){
var j=i;
setTimeout(function trimer(){
console.log(j);
},j*1000);
})();
}
在for循环里面,我们在每个迭代过程中都创建了一个闭包作用域,且作用域内定义了变量,进行了赋值。闭包改变了变量的生命周期,变量将得到永生。
小结:
闭包是隐藏在函数里面却又很厉害的。相信你已经理解了闭包,那么恭喜你,从某种意义上获得了重生!
闭包其实是一种事实,当函数可以记住并访问所在的词法作用域,即使函数是在当前词法作用域之外执行,这时就产生了闭包。闭包产生之后能够涵盖它所能访问的词法作用域。
好啦,讲完啦,如果大家觉得有错误或者改进的地方欢迎指出,只求共同进步。😄