每日一题(五一)function fn(n,o){console.log(o)return {fn:function(m){return fn(m,n)}}} const a=fn(0)a.fn(1

写出代码打印结果

function fn(n,o){
    console.log(o);
    return {
        fn:function(m){
            return fn(m,n);
        }
    };
}

const a=fn(0);a.fn(1);a.fn(2);a.fn(3);
const b=fn(0).fn(1).fn(2).fn(3);
const c=fn(0).fn(1);c.fn(2);c.fn(3);

答案:

undefined 0 0 0
undefined 0 1 2
undefined 0 1 1

解析:

闭包知识考察,return 返回的对象的 fun 属性对应一个新建的函数对象,这个函数对象将形成一个闭包作用域,使其能够访问到外层函数的变量 n 及外层函数 fun 。

关键点:理清执行的是哪个 fn 函数,为了不将 fn 函数和 fn 属性混淆,等价转化为下面代码:

function _fn_(n,o){
    console.log(o);
    return {
        fn:function(m){
            return _fn_(m,n)
        }
    }
}

const a=_fn_(0);a.fn(1);a.fn(2);a.fn(3);
const b=_fn_(0).fn(1).fn(2).fn(3);
const c=_fn_(0).fn(1);c.fn(2);c.fn(3);

1. a 执行过程:

1> const a = _fn_(0);调用最外层的函数,只传入了 n,所以打印 o 是 undefined

2> a.fn(1);调用了 fn(1) 时 m 为 1 ,此时 fn 闭包了外层函数的 n ,也就是第一次调用的 n=0 ,即 m =1 ,n= 0,并在内部调用第一层 _fn_(1,0);所以 o 为 0;

3> a.fn(2);调用 fn(2) 时 m 为 2 ,但依然是调用 a.fn,所以还是闭包了第一次调用时的 n ,所以内部调用第一层的 _fn_(2,0);所以 o 为 0

4> a.fn(3);同上

所以结果是 undefined 0 0 0

2. b 执行过程:

1> 第一次调用第一层_fn_(0) 时,o 为 undefined

2> 第二次调用 .fn(1) 时 m 为 1,此时 fn 闭包了外层函数的 n ,也就是第一次调用的 n=0,即 m=1,n=0,并在内部调用第一层的_fn_(1,0);所以 o 为 0;

3> 第三次调用 .fn(2) 时 m 为 2,此时当前的 fn 函数不是第一次执行的返回对象,而是第二次执行的返回对象。而在第二次第一层 _fn_(1,0) 时,n=1,o=0,返回时闭包了第二次的 n,所以在第三次调用第三层的 fn 函数时,m=2,n=1,即调用第一层 _fn_(2,1) 函数,所以 o 为 1;

4 > 第四次调用 .fn(3) 时 m=3,闭包了第三次的 n ,同理,最终调用第一层 _fn_(3,2);所以 o 为 2

所以结果为: undefined 0 1 2

3. c 执行过程:

1> 在第一次调用第一层 _fn_(0) 时,o 为 undefined

2> 在第二次调用, .fn(1) 时,m 为 1,此时 fn 闭包了外层函数的 n ,也就是第一次调用的 n=0,即 m=1,n=0,并在内部调用第一层 _fn_(1,0);所以 o 为 0

3> 第三次调用, .fn(2) 时 m=2,此时 fn 闭包的是第二次调用的 n=1,即 m=2,n=1,并在内部调用第一层 _fn_(2,1);所以 o 为 1

4> 第四次 .fn(3) 时同理,但依然时调用第二次的返回值,所以最终调用第一层的 _fn_(3,1),所以 o 为 1

所以结果是 undefined 0 1 1

猜你喜欢

转载自blog.csdn.net/MFWSCQ/article/details/106501331