js 閉包經典問題超詳細解析

2021-09-26 07:49:51 字數 1692 閱讀 3251

閉包經典問題如下:

function test() 

} return arr;

}var myarr = test();

for(var j = 0; j < 10; j++)

本意是想列印1到10,卻列印了10個10,為什麼呢?詳細解釋過程如下:

但此時匿名函式的作用域鏈為:

[[scope]]---->scopechain[0]---->test-ao;

---->scopechain[1]---->go;

最後,將arr返回。

[[scope]]  ---->scopechain[0]---->ao;

---->scopechain[1]---->test-ao;

---->scopechain[2]---->go;

首先在自身ao尋找i,未找到,則到下一層,test-ao尋找i,但此時由於10次迴圈都已經執行完,test-ao中i為10,因此列印了10個10。

上面列印10個10的原因是i並沒有個性化地儲存在函式的作用域鏈中,因此,我們的目的就是將其儲存在作用域鏈中。

採用立即執行函式來解決這個問題。先簡單介紹一下立即執行函式:

function test() 

} (i));

}return arr;

}var myarr = test();

for(var j = 0; j < 10; j++)

可以看出,在原來的基礎上,在arr賦值語句外層包了乙個立即執行函式,這個函式的目的就是將i的值保留在function () 的作用域鏈中,我們從頭來解析一下這個函式:

當i為0時,傳給j,此時a[0]仍被賦值為函式體function () ,但這個時候,該函式的作用域鏈為:

[[scope]]  ---->scopechain[0]---->立即執行函式的ao;

---->scopechain[1]---->test-ao;

---->scopechain[2]---->go;

此時,立即執行函式的ao為:

ao:
當i為1時,傳給j,此時a[1]仍被賦值為函式體function () ,同樣,該函式的作用域鏈為:

[[scope]]  ---->scopechain[0]---->立即執行函式的ao;

---->scopechain[1]---->test-ao;

---->scopechain[2]---->go;

此時,立即執行函式的ao為:

ao:
注:即使執行同乙個函式,每次執行均會產生不同的ao。

依此類推,可以看出,當執行陣列裡面的每個函式時,會到其作用域鏈自頂向下查詢,從而可以列印出0-9.

JS閉包解析

js作用域傳送門 function f var fn f var a 200 fn 輸出100呼叫fn函式,輸出a的值,fn中並沒有定義a,所以會向上找a,在f函式的作用域中,有a,值為100。所以就會輸出100,並不會輸出200。全域性作用域中的a和f函式作用域中的a並不相同。這也體現出了閉包的乙...

經典JS閉包題

在逛部落格時,看見乙個很有意思的閉包題,發現自己對閉包沒有完全理解,故記錄下來。先看題目 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,va...

JS經典閉包例項

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 複製 問 三行a,b,c的輸出分別是什麼?首先來看第一行 var ...