閉包的鏈式呼叫問題

2021-08-17 02:21:45 字數 1432 閱讀 2956

function

fun(n,o)

};}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,?,?,?

//問:三行a,b,c的輸出分別是什麼?

我們首先分析一下這個函式,其實這個函式是返回了乙個物件},這個函式就是閉包,因為它對函式內部作用域是可見的。好的,接下來我們繼續分析a這個變數。

var a = fun(0),fun列印的是第二個引數,這裡並沒有定義,所以返回undefined。這個時候a應該變成了fun返回的物件的乙個引用。寫清楚點就是這樣:

a = 

}

然後a.fun(1)就會呼叫fun(1,0),也就是輸出0;然後又接著返回乙個閉包,但是由於沒有物件接收它,所以並不會改變a的引用。於是,a.fun(2);a.fun(3)都只會輸出0;

接下來我們看b這個變數,var b = fun(0).fun(1).fun(2).fun(3)。初看下去很嚇人,但是我們模擬計算機的執行過程一步一步看下去,其實也沒有那麼複雜。在上文中我們提到呼叫了第乙個fun之後其實又返回了乙個函式,在這個變數中,返回的物件其實就是一直在更新。別急,我們慢慢往下看。

第一步,b=fun(0),輸出undefined,這裡和a的執行步驟是一樣的,這裡就不贅述了。不同之處在於這一行**是鏈式呼叫,後面呼叫的都是前面返回的引用。那麼fun(0)其實返回的就是fun(m,0),同時輸出undefined。而執行到fun(0).fun(1)的時候,實際上呼叫的就是:

fun(0) = 

}fun(0).fun(1) = fun(1,0) ;//輸出0

從上面的**可以看到輸出0,同時fun(0).fun(1)返回如下:

}

那麼它接下來呼叫fun(0).fun(1).fun(2)會輸出什麼呢?很顯然就是輸出1啦。同樣的道理,fun(0).fun(1).fun(2).fun(3)就會輸出2。所以執行這一句,控制台會列印出undefined,0,1,2。

而對於變數c,其實就是變數a和變數b的組合。可以說整道題考察的重點就是到底有沒有物件來接收函式的返回值(引用),對c來說,它所執行的fun(2),fun(3)雖然返回了乙個物件,但是沒有像var c = fun(0).fun(1)一樣被變數接收,所以就不會執行return裡面的方法。

像這種問題雖然看起來複雜,但是細細往下理解發現原來也就那樣。閉包,也就這樣。

我想要拼搏的未來,最後發現你卻已不在

閉包 解決閉包問題

1 函式和對其周圍狀態 lexical environment,詞法環境 的引用 在一起構成閉包 closure 2 函式與函式所依賴的上下文環境組成閉包問題。3 閉包指的是 能夠訪問另乙個函式作用域的變數的函式。清晰的講 閉包就是乙個函式,這個函式能夠訪問其他函式的作用域中的變數。var arr ...

延時問題的鏈式呼叫

問題 function queue 實現佇列queue的兩個方法 add timeout,callback 給佇列中新增方法 start 執行佇列中的方法,執行完之後佇列清空 實現鏈式呼叫 例如 var que newqueue que.add 1000 function add 2000 func...

整理的閉包問題

給大家整理了下閉包的相關問題,能幫助加深對閉包的理解。function f1 function f2 return f2 var result f1 result 999 nadd result 1000 第一步,result是f2函式 第二步,執行result就是執行f2函式,又因為閉包使得f2能...