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)  // undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3)  // undefined,?,?,?
var c = fun(0).fun(1); c.fun(2); c.fun(3)  // undefined,?,?,?

以上三题分别打印出什么?

此题出自这里

这已经不是我第一次看这套题了。第一次看到这题的时候,我没有完全做出来,感觉里面的fun函数(方法)太绕了,做到后面都晕了,不知道到底指的是哪个fun。于是花了半天时间把这几套题搞懂了(当时觉得自己搞懂了,捂脸),隔了两天我把题目拿给其他人做,顺便打算自己讲一遍给对方听,发现自己又傻又晕了,最后还给人笑了(哭)。然后又看了第二遍,又感觉懂了。今天浏览网页的时候,又翻到这个,想着看能不能做出来。我是拿着纸笔写的,又发现自己要晕了。终于决定:不行,我得自己写一遍这个思考过程,不然下次我还得晕~~~。所以就有了下面这篇思考分析。

分析如下:

tips:我把外层的fun叫做函数fun,return 里面的fun我叫方法fun。这里很关键,分清楚这两个就比较不容易错了

第一道:var a = fun(0); a.fun(1); a.fun(2); a.fun(3) // undefined,?,?,?

第一步:执行fun(0),将参数代入函数fun,看看执行情况
var a = fun(0) = (function(n=0){
    console.log(o);          // undefined;因为没有第二个参数o。
    return {                 // return后面是带着fun方法的对象,对象里面的内容不作执行,但会带上n这个自由变量的值0;
        fun:function(m){
            return fun(m,0)  // 这里的n是0
        }
    }
})(0)
所以a = fun(0)打印的值:undefined
返回的值为:
var a = fun(0) = {
    fun:function(m){
        return fun(m,0)
    }
}

第二步:执行a.fun(1),即执行对象a的方法fun(m),而方法fun(m)又return回函数fun(m,0),最终执行的是这个函数fun(m,0),这里的m就是1
a.fun(1) = (function fun(m=1){
    return fun(1,0)  // 该方法将返回函数fun(1,0),而函数fun(1,0)又将按第一步一样执行一次。
})(1)
即:
a.fun(1) = fun(n=1,o=0) = (function(n=1,o=0){
    console.log(0)           // 0; 这里的0就是第二个参数o
    return {                 // return带fun方法的对象
        fun: function(m){
            return fun(m,1)  // 这里的n是1
        }
    }
})(1,0)

所以a.fun(1)打印的值为:0
返回的值为:
a.fun(1) = {
    fun:function(m){
        return fun(m,1)
    }
}

第三步:执行a.fun(2),即执行对象a的fun方法,同第二步,只是参数有变,最终执行的是函数fun(2,0)
a.fun(2) = (function fun(m=2){
    return fun(2,0)
})(2)
即:
a.fun(2) = fun(n=2,o=0) = (fun(n=2,o=0){
    console.log(0);       // 0,这里的0即是o这个参数
    return fun: function(m){
        return fun(m,2)  // 这里的n是2 
    }
})(2)
所以a.fun(2)打印的值为:0
返回的值为:
a.fun(2) = {
    fun: function(m){
        return fun(m,2)
    }
}

第四步:a.fun(3),同第二、第三步(过程略),最终执行的是函数fun(3,0)
所以a.fun(3)打印的值为: 0
返回的值为:
a.fun(3) = {
    fun: function(m){
        return fun(m,3)
    }
}

第二道:var b = fun(0).fun(1).fun(2).fun(3) // undefined,?,?,?

第一步:先执行fun(0)
由上面第一道分析可知: fun(0) 打印的值为:undefined
返回的值为:
fun(0) = {
    fun:function(m){
        return fun(m,0)
    }
}

第二步:执行fun(0).fun(1),其实这里也和上面第一道的第二、三、四步是一样的
fun(0).fun(1)即执行fun(0)的方法fun(),而方法fun()又将return回函数fun(m,0),所以,fun(0).fun(1)最终执行的是函数fun(m,0),m就是参数1。
fun(0).fun(1) = fun(n=1,o=0) = (function(n=1,o=0){
    console.log(0)           // 0,第二个参数o
    return {
        fun: function(m){
            return fun(m,1)  // 这里的n是1
        }
    }
})(1,0)

所以fun(0).fun(1)打印的值为:0
返回的值为:
fun(0).fun(1) = {
    fun: function(m){
        return fun(m,1)
    }
}

第三步:执行fun(0).fun(1).fun(2),即执行fun(0).fun(1)的方法fun(2),fun(2)又返回函数fun(2,1),所以fun(0).fun(1).fun(2)最终执行的是函数fun(2,1)
fun(0).fun(1).fun(2) = fun(n=2,o=1) = (function(n=2,o=1){
    console.log(1);          // 1,第二个参数o
    return {
        fun: function(m){
            return fun(m,2)  // 这里的n是2
        }
    }
})(2,1)

所以fun(0).fun(1).fun(2)打印的值为:1
返回的值为:
fun(0).fun(1).fun(2) = {
    fun: function(m){
        return fun(m,2)
    }
}

第四步:执行fun(0).fun(1).fun(2).fun(3), 按上面分析,这里最终执行的是函数fun(3,2)
fun(0).fun(1).fun(2).fun(3) = fun(n=3,o=2) = (function(n=3,o=2){
    console.log(2);          // 2,第二个参数o
    return {
        fun: function(m){
            return fun(m,3)  // 这里的n是3
        }
    }
})(3,2)

所以fun(0).fun(1).fun(2).fun(3)打印的值为:2
返回的值为:
fun(0).fun(1).fun(2).fun(3) = {
    fun: function(m){
        return fun(m,3)
    }
}

第三道:var c = fun(0).fun(1); c.fun(2); c.fun(3) // undefined,?,?,?

由上面分析可知:(第二道第二步返回的值)
var c = fun(0).fun(1) = {
    fun: function(m){
        return fun(m,1)
    }
}
打印的值为: 0

接下来分析后面的题
第一步:执行c.fun(2), return回函数fun(2,1),最终执行的也是函数fun(2,1)。其实这也和第二道的第三步是一样的。
c.fun(2) = fun(n=2,o=1) = (function(n=2,o=1){
    console.log(1)           // 1,第二个参数是1
    return {
        fun: function(m){
            return fun(m,2)  // 这里的n是2
        }
    }
})(2,1)

所以c.fun(2)打印的值为:1
返回的值为:
c.fun(2) = {
    fun : function(m){
        return fun(m,2)
    }
}

第二步:执行c.fun(3),return回函数fun(3,1),也是最终执行的函数。同第一步。
所以c.fun(3)打印的值为:1
返回的值为:
c.fun(3) = {
    fun: function(m){
        return fun(m,3)
    }
}

为了方便对比这三道题的结果,用表格记录如下:

表头 第一题 第二题 第三题
fun(0) undefined undefined undefined
a.fun(1)
fun(0).fun(1)
fun(0).fun(1)
0 0 0
a.fun(2)
fun(0).fun(1).fun(2)
fun(0).fun(1).fun(2)
0 1 1
a.fun(3)
fun(0).fun(1).fun(2).fun(3)
fun(0).fun(1).fun(3)
0 2 1

通过分析过程可知,有两点是需要注意的:

  1. 最终执行的始终是fun函数,就是最外层的function,因为执行它才有打印的值。
  2. 参数的变化。方法fun和函数fun的参数是不一样的,而且它们之间的参数有交叉,所以很容易弄混。
内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!

相关课程