前言
大家好,本人来在掘金待了有3个多月了,决定跟随前端大佬们的步伐,故决定每天一题记录自己的成长轨迹,由于水平有限,对于文章中出现的问题还请大佬们指正。
先来瞄看一眼这个笔试题
function fun(n,o) {
console.log(o)
return {
fun:function(m){
return fun(m,n);
}
}
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
复制代码
如果你的反应是:
那就继续往下看,相反对于丝毫无压力的童鞋就可以快乐的去玩耍了!可以看到本题考查的知识点主要是闭包!
分层逐一攻破
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
复制代码
1.先来看第一句第一条调用语句:fun(0);
毋庸置疑肯定是在调用最外层的fun
函数,调用时传了0
这个参数,因为最外层的fun
函数有两个形参,传的时候只传递了一个。那么也就是说这个n
对应的是0
,那么显然o
是没有值的,所以o
就是undefined
,所以第一次输出o
就是undefined
,但还需要注意一点,第一条执行完毕后,将他的执行结果赋值给了a
变量,因为全局的fun
函数里还return
了一个函数,所以我们称这种函数为闭包函数!所以这里的a现在实际上是这样一个玩意儿:
fun:function(m){
return fun(m,n);
}
复制代码
2.再来看第一句第二条调用语句:a.fun(1);
,注意啦,这里使用变量a
调用了fun
,也就是说这里调用的fun
实际上是刚刚返回的闭包函数。 那可以很显然的看到,这个闭包函数接收一个参数。咱们现在只传递了一个参数那就是1(所以形参 m = 1)
,重点又来了,你会发现里面又return
了一个函数,且里面多了一个参数n
,这里的n
其实是闭包了上面的全局函数fun
中的n
,因为闭包会创建出一个不被销毁的作用域,所以n
还保留在内存中,那这里的n
的值也就是第一句第一条(fun(0)
)调用语句接收到的0 所以这里的m=1,n=0
,那刚刚也提到了里面又return
了一个全局函数fun(m,n)
,所以就是o=0 (o对应的就是全局函数形参中的n)
3.再来看第一句第三条调用语句:a.fun(2)
时m
为2
,所以还是闭包了第一次调用时的n,所以内部调用第一层的fun(2,0);所以o为0
4.再来看第一句第四条调用语句:a.fun(3)
时m
为3
,所以还是闭包了第一次调用时的n,所以内部调用第一层的fun(3,0);所以o为0
因此可以看到第一个fun(0)是在调用第一层fun函数。 第二个fun(1)是在调用前一个fun的返回值的fun函数,所以: 后面几个fun(1),fun(2),fun(3),函数都是在调用第二层fun函数。
即: 本题最终执行后的输出结果为undefined,0,0,0
总结
可以看到这道题对闭包的考察彻头彻尾,从始至终都离不开闭包,通过这道题我们得出结论:创建闭包可以保存一个或多个变量,供我们循环利用。 但切记闭包很可能会导致内存占用过大。因此我们应该理性的使用闭包给我们带来的好处。
好啦,到这里给大家留一个习题,接着上面的题目,我们再追加一条调用语句,大家可以试着自己做一下,做完后可以参考下面的答案,看自己的结果是否正确
var b = fun(0).fun(1).fun(2).fun(3);
请输出上面这条语句的输出结果。
补充的题目的答案我会在评论区给出
大佬们如果发现了文中的错误,及时在评论区指出,我会及时修改!
如果觉得对您有用请点个赞,谢谢大佬!