JavaScript - 闭包经典练习题2 - ‘套娃’

function fun (n,o){
	console.log(o);
	return {
		fun:function(m){
			return fun(m, n);
		};
	};
};
var c  = fun(0).fun(1);
c.fun(2);
c.fun(3);

图形解析:
请添加图片描述
文字步骤解析:

  1. 全局上下文中进行变量提升。
    1. function fun (n,o){...};,函数在变量提升阶段,定义加赋值。-> function fun = 0x000
    2. var关键字声明的变量,在变量提升阶段,只声明不定义 ->var c (默认undefined)
  2. 代码执行:
    1. function fun (n,o){...};,函数在变量提升阶段,定义加赋值过,此处直接跳过。
    2. var c = fun(0).fun(1);
      1. var c变量提升阶段提升阶段已经处理过,只需要把等号右侧运算出来,把结果赋值给全局变量 c 即可。
      2. 运算 fun(0).fun(1);分两步骤运算:
        1. 第一步:fun(0) => 0x000(0)
          1. 初始化作用域链 /初始化this/ 变量提升…n = 0, o = undefined
          2. 代码执行:
            1. console.log(o); =>第一次输出 ‘undefined’
            2. return {... }; => 0x001
          3. 得出运算结果对象堆 0x001
        2. 第二步,0x000(0).fun(1):对象堆 0x001 中的函数堆 0x002 执行,并传参数1,-> 0x002(1)
          1. 初始化作用域链 /初始阿虎this/ 变量提升…m = 1
          2. 代码执行:return fun(m, n);
            1. 此处是第二次运行全局函数fun,并传参m ,n -> 0x000(1, 0)
              1. 初始化作用域链 /初始化this/ 变量提升…n = 1,0 = 0
              2. 代码执行:
                1. console.log(o); =>第二次输出 ‘0’
                2. return {... }; => 0x003
            2. 返回新的对象堆 0x003
        3. 返回新的对象堆 0x003返回给上下文EC(AN)
      3. 再把返回的对象堆 0x003 赋值给全局的变量 c
      4. 此时上下文EC(AN)中对象堆被上下文以外的全局变量从c占用了,所以上下文EC(AN)不能被释放,就形成了闭包。
    3. c.fun(2);
      1. 执行变量c的对象堆 0x003 中的函数堆fun: 0x004,并传入参数 2 =>fun(0) => 0x000(2)
      2. 初始化作用域链 /初始阿虎this/ 变量提升…m = 2
      3. 代码执行:return fun(m, n);
        1. 此处是第三次运行全局函数fun,并传参m ,n -> 0x000(2, 1)
          1. 初始化作用域链 /初始化this/ 变量提升…n = 2,0 = 1
          2. 代码执行:
            1. console.log(o); =>第三次输出 ‘1’
            2. return {... }; => 0x005
          3. 返回新的对象堆0x005
      4. 返回的对象没有被占用,所以当前上下文出栈释放。
    4. c.fun(3);
      1. 执行变量c的对象堆 0x003 中的函数堆fun: 0x004,并传入参数 3 =>fun(0) => 0x000(3)
      2. 初始化作用域链 /初始阿虎this/ 变量提升…m = 3
      3. 代码执行:return fun(m, n);
        1. 此处是第三次运行全局函数fun,并传参m ,n -> 0x000(3, 1)
          1. 初始化作用域链 /初始化this/ 变量提升…n = 3,0 = 1
          2. 代码执行:
            1. console.log(o); =>第四次输出 ‘1’
            2. return {... }; => 0x007
          3. 返回新的对象堆0x007
      4. 返回的对象没有被占用,所以当前上下文出栈释放。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值