徹底弄懂JS中閉包

2021-09-16 23:46:01 字數 1702 閱讀 1621

閉包概念:

閉包就是有權訪問另乙個函式作用域中變數的函式.

分析這句話:

1.閉包是定義在函式中的函式.

2.閉包能訪問包含函式的變數.

3.即使包含函式執行完了, 被閉包引用的變數也得不到釋放.

例子分析-1:

function add());

}return arr;

}var temp = add();

temp[0]();

大家猜猜這個結果是多少? 0, i, 10?

我想大家會說是0.

但是結果是10.

我想大家想的應該是這樣滴:

i = 0, arr.push(function())

i = 1, arr.push(function())

...i = 10, arr.push(function())

咋一看, 這個確實合理, 根據閉包的定義, 具體這個當然是上面分析的那樣了.

問題就出在這個變數的理解上.

1.i是變數不假, 但是i在for迴圈的時候, 一直在不斷變化. 也就是說這個i在參與for迴圈的時候, 值是不確定的, 等到for執行完後, i的值才確定.

2.每次push乙個匿名函式表示式時, 那只是定義乙個函式, 並沒去執行那個函式, 所以那個函式裡引用的外部變數都是原封不動的放進去的.

換句話說, 就是這個匿名函式在最後執行的時候, 才會去查詢作用域鏈, 直至找到那個變數i為止.

也就是:

i = 0, arr.push(function())

i = 1, arr.push(function())

...i = 10, arr.push(function())

執行add()時, i參與迴圈完畢, i = 10.

執行temp[0]()時, 匿名函式會查詢i, 先看自己, 我的i有值嗎?沒有. 再找他的上級函式, i有值嗎?有, i = 10. 查詢結束.

至此, 不管執行temp[0](), 還是temp[5](), 還是temp[10](), 結果都是10.

改一下上面的例子, 讓它符合我們的預期要求.

例子分析-2:

function add()

})(i)//注意這個變化);}

return arr;

}var temp = add();

temp[0]();

temp[1]();

...這次結果是預期的,結果是 0 , 1 , 2, 3 ... 10

分析一下迴圈那部分.

(function(n)

})(i)

這個叫做立即執行的匿名函式表示式(不清楚這種寫法的, 可以先google下, 或者看我的單獨一篇專門介紹)

i這個是時候就被當做引數傳遞了, 每次這個匿名函式執行時, i都會把自己的值複製乙份給n

return語句中的匿名函式引用著n, 此時已經和i無關了.

每次匿名函式表示式執行時, 都會儲存乙個不同的n.

return語句中的匿名函式每次也引用著不同的n。

形象點就是這樣:

arr.push(

(function(n = i = 0)

})(i = 0)

)arr.push(

(function(n = i = 1)

})(i = 1)

)...

閉包的介紹就到此為止了.

**

徹底理解js中的閉包

閉包是js的乙個難點也是它的乙個特色,是我們必須掌握的js高階特性,那麼什麼是閉包呢?它又有什麼用呢?我們都知道,js的作用域分兩種,全域性和區域性,基於我們所熟悉的作用域鏈相關知識,我們知道在js作用域環境中訪問變數的權利是由內向外的,內部作用域可以獲得當前作用域下的變數並且可以獲得當前包含當前作...

徹底弄懂js中的this指向

可以先參考這篇部落格 全域性作用域或者普通函式中this指向全域性物件window。直接列印 console.log this window function宣告函式 function bar bar window function宣告函式賦給變數 var bar function bar wind...

徹底搞懂閉包

恢復內容開始 1 閉包的定義 官方的解釋是 所謂 閉包 指的是乙個擁有許多變數和繫結了這些變數的環境表示式 通常是乙個函式 因而這些變數也是這些表示式的一部分。相信很多人看完這個很難懂,其實在不懂之前我也看不懂。先看一段 function a return b var c a c 這個函式有兩個特點...