经典闭包题解析

MoMaek

共 2746字,需浏览 6分钟

 ·

2021-06-12 17:58

问:

下面代码中,标记?的地方输出分别是什么?

function fun(n, o{
    console.log(o)
    return {
        funfunction (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


浏览 30
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报