以上三題分別列印出什麼? 此題出自 "這裡" 這已經不是我第一次看這套題了。第一次看到這題的時候,我沒有完全做出來,感覺裡面的fun函數(方法)太繞了,做到後面都暈了,不知道到底指的是哪個fun。於是花了半天時間把這幾套題搞懂了(當時覺得自己搞懂了,捂臉),隔了兩天我把題目拿給其他人做,順便打算自己 ...
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 |
通過分析過程可知,有兩點是需要註意的:
- 最終執行的始終是fun函數,就是最外層的function,因為執行它才有列印的值。
- 參數的變化。方法fun和函數fun的參數是不一樣的,而且它們之間的參數有交叉,所以很容易弄混。