经典闭包题解析
共 2746字,需浏览 6分钟
·
2021-06-12 17:58
问:
下面代码中,标记?
的地方输出分别是什么?
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 b = fun(0).fun(1).fun(2).fun(3); // ?
var c = fun(0).fun(1); // ?
c.fun(2); // ?
c.fun(3); // ?
解析:
一、a
var a = fun(0);a.fun(1);a.fun(2);a.fun(3);
第一个fun(0)
调用的是第一层函数,同时返回了一个闭包对象,即:
function fun(n = 0, o = undefined) {
console.log(o) // undefined
return ...
}
所以这时候控制台会打印undefined
,并且这时a={ fun: function(m) }
接下来执行a.fun(1)
,这时候会调用第二层匿名函数,也就是:
{
fun:function(m = 1){
return fun(m = 1, n = 0);
}
}
形参m = 1
,并且再次调用第一层函数,这时候n
已经在第一层函数时变为了0
,所以形参o = 0
,即:
function fun(n = 1, o = 0) {
console.log(o) // 0
return ...
}
接下来执行a.fun(2)
,同上一样,只会改变m
的值,n
的值并不会改变,所以:
{
fun:function(m = 2){
return fun(m = 2, n = 0);
}
}
function fun(n = 2, o = 0) {
console.log(o) // 0
return ...
}
a.fun(3)
也一样:
{
fun:function(m = 3){
return fun(m = 3, n = 0);
}
}
function fun(n = 3, o = 0) {
console.log(o) // 0
return ...
}
所以得出第一个答案
a: undefined,0,0,0
二、b
var b = fun(0).fun(1).fun(2).fun(3);
第一个fun(0)
调用的是第一层函数,同时返回了一个闭包对象,即:
function fun(n = 0, o = undefined) {
console.log(o) // undefined
return ...
}
所以这时候控制台会打印undefined
,并且这时b={ fun: function(m) }
接下来执行.fun(1)
,这时候会调用第二层匿名函数,也就是:
{
fun:function(m = 1){
return fun(m = 1, n = 0);
}
}
形参m = 1
,并且再次调用第一层函数,这时候n
已经在第一层函数时变为了0
,所以形参o = 0
,即:
function fun(n = 1, o = 0) {
console.log(o) // 0
return ...
}
接下来执行.fun(2)
,会调用第二层匿名函数,并且第二层匿名函数中闭包了第一层函数,这时形参n
已经由第一层函数时变为了1
,即:
{
fun:function(m = 2){
return fun(m = 2, n = 1);
}
}
function fun(n = 2, o = 1) {
console.log(o) // 1
return ...
}
接下来的.fun(3)
同上一样:
{
fun:function(m = 3){
return fun(m = 3, n = 2);
}
}
function fun(n = 3, o = 2) {
console.log(o) // 2
return ...
}
所以得出第二个答案
b: undefined,0,1,2
三、c
var c = fun(0).fun(1);c.fun(2);c.fun(3);
第一个fun(0)
调用的是第一层函数,同时返回了一个闭包对象,即:
function fun(n = 0, o = undefined) {
console.log(o) // undefined
return ...
}
所以这时候控制台会打印undefined
,并且这时c={ fun: function(m) }
接下来执行.fun(1)
,这时候会调用第二层匿名函数,也就是:
{
fun:function(m = 1){
return fun(m = 1, n = 0);
}
}
形参m = 1
,并且再次调用第一层函数,这时候n
已经在第一层函数时变为了0
,所以形参o = 0
,即:
function fun(n = 1, o = 0) {
console.log(o) // 0
return ...
}
接下来执行c.fun(2)
,这时候会调用第二层匿名函数,也就是:
{
fun:function(m = 2){
return fun(m = 2, n);
}
}
形参m = 2
,并且再次调用第一层函数,这时候形参n
已经在执行.fun(1)
时变为了1
,所以形参o = 1
,即:
function fun(n = 2, o = 1) {
console.log(o) // 1
return ...
}
接下来执行c.fun(3)
,同上一样:
{
fun:function(m = 3){
return fun(m = 3, n);
}
}
形参m = 3
,并且再次调用第一层函数,这时候形参n
已经在执行.fun(1)
时变为了1
,所以形参o = 1
,即:
function fun(n = 2, o = 1) {
console.log(o) // 1
return ...
}
注意:c,fun(2)
和c.fun(3)
是分开执行的,都没有改变c
的值,所以这两个函数并不会影响传入的参数n
所以得出第三个答案
c: undefined,0,1,1