經典 JS 閉包面試題

尖子發表於2024-09-11
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,?,?,?
答案:
undefined 0 0 0
undefined 0 1 2
undefined 0 1 1
解答:

1、第一行a

vara=fun(0);a.fun(1);a.fun(2);a.fun(3);

可以得知,第一個fun(0)是在呼叫第一層fun函式。第二個fun(1)是在呼叫前一個fun的返回值的fun函式,所以:第後面幾個fun(1),fun(2),fun(3),函式都是在呼叫第二層fun函式。

遂:

在第一次呼叫fun(0)時,o為undefined;

第二次呼叫fun(1)時m為1,此時fun閉包了外層函式的n,也就是第一次呼叫的n=0,即m=1,n=0,並在內部呼叫第一層fun函式fun(1,0);所以o為0;

第三次呼叫fun(2)時m為2,但依然是呼叫a.fun,所以還是閉包了第一次呼叫時的n,所以內部呼叫第一層的fun(2,0);所以o為0

第四次同理;

即:最終答案為undefined,0,0,0

2、第二行b

var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?

先從fun(0)開始看,肯定是呼叫的第一層fun函式;而他的返回值是一個物件,所以第二個fun(1)呼叫的是第二層fun函式,後面幾個也是呼叫的第二層fun函式。

遂:

在第一次呼叫第一層fun(0)時,o為undefined;

第二次呼叫 .fun(1)時m為1,此時fun閉包了外層函式的n,也就是第一次呼叫的n=0,即m=1,n=0,並在內部呼叫第一層fun函式fun(1,0);所以o為0;

第三次呼叫 .fun(2)時m為2,此時當前的fun函式不是第一次執行的返回物件,而是第二次執行的返回物件。而在第二次執行第一層fun函式時時(1,0)所以n=1,o=0,返回時閉包了第二次的n,遂在第三次呼叫第三層fun函式時m=2,n=1,即呼叫第一層fun函式fun(2,1),所以o為1;

第四次呼叫 .fun(3)時m為3,閉包了第三次呼叫的n,同理,最終呼叫第一層fun函式為fun(3,2);所以o為2;

即最終答案:undefined,0,1,2

3、第三行c

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

根據前面兩個例子,可以得知:

fun(0)為執行第一層fun函式,.fun(1)執行的是fun(0)返回的第二層fun函式,這裡語句結束,遂c存放的是fun(1)的返回值,而不是fun(0)的返回值,所以c中閉包的也是fun(1)第二次執行的n的值。c.fun(2)執行的是fun(1)返回的第二層fun函式,c.fun(3)執行的也是fun(1)返回的第二層fun函式。

遂:

在第一次呼叫第一層fun(0)時,o為undefined;

第二次呼叫 .fun(1)時m為1,此時fun閉包了外層函式的n,也就是第一次呼叫的n=0,即m=1,n=0,並在內部呼叫第一層fun函式fun(1,0);所以o為0;

第三次呼叫 .fun(2)時m為2,此時fun閉包的是第二次呼叫的n=1,即m=2,n=1,並在內部呼叫第一層fun函式fun(2,1);所以o為1;

第四次.fun(3)時同理,但依然是呼叫的第二次的返回值,遂最終呼叫第一層fun函式fun(3,1),所以o還為1

即最終答案:undefined,0,1,1

來源: https://www.sohu.com/a/422560066_744986

相關文章