網上經典閉包面試題解析

2022-02-20 11:52:52 字數 2335 閱讀 4207

**a

function

fun(n,o)

}}var a=fun(0);

a.fun(1);

a.fun(2);

a.fun(3);

var b=fun(0).fun(1).fun(2).fun(3);

var c=fun(0).fun(1);

c.fun(2);

c.fun(3);

求出程式輸出

這是乙個閉包測試題

return返回的物件的fun屬性對應乙個新建的函式物件,這個函式物件將形成乙個閉包作用域,使其能夠訪問外層函式的變數n及外層函式fun,為了不將fun函式和fun屬性搞混,我們將上述**修改如下:**b

function

_fun_(n,o)

}}var a=_fun_(0);//

undefined

a.fun(1);//

0a.fun(2);//

0a.fun(3);//

0var b=_fun_(0).fun(1).fun(2).fun(3);

//undefined,0,1,2

var c=fun(0).fun(1);//

undefined,0,

c.fun(2);//

1c.fun(3); //

1

那麼就有同學問了,為什麼可以這樣改呢,你怎麼能確定[1]處的fun不是[2]**所在處的fun呢,要知道此處的fun屬性可是指向乙個函式物件哦~

這裡就要說到js的詞法作用域,js變數作用域存在於函式體中即函式體,並且變數的作用域是在函式定義宣告的時候就是確定的,而非在函式執行時。

如下**

var name="global";

function foo()

function fooouter1()

fooouter1();//輸出global 而不是local,並且和閉包沒有任何關係

function fooouter2()

foo();

}fooouter2();//輸出local 而不是global,在函式宣告是name變數作用域就在其外層函式中,嗯嗯就是閉包~

好了我們回到題目,在函式宣告定義階段,[2]處的匿名函式進行定義宣告,發現在[1]處需要引用乙個名為fun的函式物件,那麼首先在當前函式體內尋找,發現沒有,那麼就到其外層函式-這個匿名函式的包裹函式中去查詢,發現也沒有,到外層函式中去,發現外面沒有函式包裹了,那就到全域性環境下去找,額偶終於找到了......就把fun函式指定為全域性環境下的fun函式物件並加入到匿名函式的閉包中去。至此我們就知道**b為什麼和**a是等價的了~~~

js在詞法分析結束後,確定了1個閉包,就是返回的物件fun屬性對應的匿名函式的閉包-訪問全域性環境下的_func_及其外層函式的函式內部變數n;在每次_func_執行的時候,都會將閉包中變數的作用域資訊傳遞到函式執行環境中,供函式執行時獲取變數值時使用

var a=_fun_(0);//undefined

a.fun(1);//0

a.fun(2);//0

a.fun(3);//0

_fun_函式執行,因為第2個引數未定義,輸出undefined。然後返回乙個物件,帶有fun屬性,指向乙個函式物件-帶有閉包,能夠訪問到_fun_和變數n_

a.fun(1)執行返回的物件的fun方法,傳入m的值1,呼叫返回_fun_(1,0)

所以輸出為0,a.fun(2),a.fun(3)a.fun(1)

var b=_fun_(0).fun(1).fun(2).fun(3);
等價**

var b=_fun_(0);

var b1=b.fun(1);

var b2=b1.fun(2);//[3]

var b3=b2.fun(3);//[4]

前2句和上面的輸出相同undefined,0,當[3]被呼叫時,b1物件中有乙個閉包,引用了_fun_函式及外層函式變數n=1,所以匿名函式執行的函式呼叫為_fun_(2,1),輸出結果為1,並返回乙個新的物件。當[4]執行時,b2物件也有乙個閉包,引用了_fun_函式及外層函式變數n=2,執行_fun_(3,2),輸出結果為2

var c=fun(0).fun(1);//undefined,0,

c.fun(2);//1

c.fun(3); //1

能看懂前面的**執行解釋,理解上面的**執行輸出就不會有問題了

javascript閉包經典面試題

首先第一行,先看 var a fun 0 把0傳入 fun n,o 中,那麼 n 0,o undifine,而 fun n,o return 了 所以a就等於 所以a.fun 1 function 1 fun 1,0 所以會輸出0,同樣a.fun 2 function 2 fun 2,0 輸出0,以...

面試題解析

1.繼承執行順序 當兩個類之間有繼承關係時,第一次構造子類的例項時,是按照如下順序進行的 1.子類的靜態成員初始化語句 2.子類的靜態建構函式 3.子類的非靜態成員初始化語句 4.父類的靜態成員初始化語句 5.父類的靜態建構函式 6.父類的非靜態成員初始化語句 7.父類的建構函式 8.子類的建構函式...

面試題 閉包問題

function console.log y console.log x console.log y 輸出結果為 1 console.log x 輸出結果為 error,直接報錯 解析宣告變數 從右向左賦值,可分解為 y 1 var x y 可見 y 為全域性變數,x為閉包函式內的區域性變數,在co...