闭包堆栈的小题

写出执行以下代码的结果:

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);

代码运行的过程,在以下代码中:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>闭包堆栈的小题</title>
</head>

<body>
    <script>
        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); //=> undefined 0 1 1
        // 输出结果为:undefined 0 1 1,执行过程如下:
        /*
            ECSTack:
            EC(G):
                VO(G):
                    Fun ,创建一个变量fun,并且创建一个堆,并将这个堆赋值给Fun,Fun = AAAFFF000。
                    var c = fun(0).fun(1); =>先创建变量c,然后执行fun(0),而后将结果.fun(1)执行,最后将这个结果赋值给变量c。执行结果如下:
                    因为是函数,所以会创建有一个新的执行上下文,称为EC(FUN)1,也就是fun(0),里面的内容为:
                        变量对象:AO(FUN)1;作用域链为:<--,VO(G)>
                            传递的实参个数,arguments=1
                            形参赋值:
                                n = 0,
                                o = undefined
                        代码执行:
                        console.log(o) =>undefined
                        return {fun:function(m){return fun(m,n)}},在此返回一个对象,创建一个新的堆对象,名为AAAFFF111,fun(0)执行后,要执行"结果.fun(1)",即AAAFFF111.fun(1),会产生一个新的执行上下文,anonymous是匿名的意思,可以称上下文为EC(AM)1,里面的内容为:
                            创建变量对象AO(AM)1 ; 作用域链<AO(AM)1,AO(FUN)1>
                                传递的实参个数,arguments=1
                                形参赋值:m=1
                                代码执行:return fun(m,n),m是1,而n本作用域没有,向上级找,在AO(FUN)1
中,n为0,=>所以是return fun(1,0),先执行fun(1,0).然后将这个的函数结果返回,故创建新的上下文,再一次执行fun():
        EC(FUN)2:=> fun(1,0)
            创建变量:AO(FUN)2;作用域链:<AO(FUN)2,VO(G)>,上级作用域链是找在哪里创建的,Fun是在全局创建的所以,是VO(G)
                传递的实参个数,arguments=2
                形参赋值:
                    n:1,
                    o:0
            代码执行:
                console.log(o)=>0
                return {
                    fun:function(){...}
                },返回一个对象,在此是将这个返回的结果给c,所以这个return对象就是c,因是在AO(FUN)2中创建的,上级作用域就是AO(FUN)2。
            c.fun(2);=>执行c中的fun函数,会创建新的执行上下文,EC(AM)2,传个2 => AM(2):
                创建变量对象AO(AM)2;作用域链:<AO(AM)2,AO(FUN)2>
                    传递的实参个数:arguments=1;
                    形参赋值:m=2;
                    代码往下执行:
                        return fun(m,n)=> m是2,n在本作用域中没有,向上级查找,就是AO(FUN)2中,n=1,即return fun(2,1),要执行fun(2,1),然后将执行结果返回,所以就是fun()第三次执行,会形成新的执行上下文,即EC(FUN)3: => fun(2,1)
                            里面的执行:
                                创建新的变量对象AO(FUN)3;作用域链为<AO(FUN)3,VO(G)>因为fun是在全局创建,所以上级为VO(G)。
                                fun(2,1) => 因为在上述代码中直接return fun(m,n),即fun(2,1),接下来就是执行fun(2,1):
                                    传递的实参个数为:arguments=2
                                    形参赋值:
                                        n:2,
                                        o:1
                                    代码执行:
                                        console.log(o) =>1
                                        return{
                                            fun:function(){...}
                                        }
            c.fun(3)=>执行c中的fun函数,会创建新的执行上下文,EC(AM)3,传个3 => AM(3):
                创建变量对象AO(AM)3;作用域链:<AO(AM)3,AO(FUN)2>
                    传递的实参个数:arguments=1;
                    形参赋值:m=3;
                    代码往下执行:
                        return fun(m,n)=> m是3,n在本作用域中没有,向上级查找,就是AO(FUN)2中,n=1,即return fun(3,1),要执行fun(3,1),然后将执行结果返回,所以就是fun()再次执行,会形成新的执行上下文,即EC(FUN)4: => fun(3,1)
                            里面的执行:
                                创建新的变量对象AO(FUN)4;作用域链为<AO(FUN)4,VO(G)>因为fun是在全局创建,所以上级为VO(G)。
                                fun(3,1) => 因为在上述代码中直接return fun(m,n),即fun(2,1),接下来就是执行fun(3,1):
                                    传递的实参个数为:arguments=2
                                    形参赋值:
                                        n:3,
                                        o:1
                                    代码执行:
                                        console.log(o) =>1
                                        return{
                                            fun:function(){...}
                                        }

        */
    </script>
</body>
</html>

如下图:
堆栈小题运行过程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值