我終於理解了閉包

2022-09-17 19:00:12 字數 1558 閱讀 9759

本文寫於 2020 年 5 月 14 日

閉包這個詞一聽就很高階,令人害怕。

但實際上,閉包非常的強大,js 的精髓之一就是閉包。

實際上,我們經常在使用閉包,而不自知!

kyle simpson 在書中將掌握閉包,比喻為:

不像 luke 一樣接受訓練才能掌握原力,而是像 neo 見到矩陣一樣。

我們其實一直都在不自覺地使用著閉包,一旦理解了閉包,就會如同重生一般,鳳凰涅槃。

function foo()
這個非常簡單的函式,如果呼叫foo(),那麼在短暫的時間過後,hello 變數就會消失的無影無蹤。

彷彿從來沒有出現過一樣。

但是如果我們這麼寫:

function foo() 

return bar

}let hey = foo()

觀察一下,雖然在let hey = foo()的時候,foo 已經執行過了,但是如果我們使用hey(),依然可以使用 hello 變數!

這就是閉包。

foo()在執行之後,正常情況下,整個內部的作用域都會被銷毀,因為 js 引擎會幫助我們自動**垃圾。

而閉包神奇的可以阻止這件事情的發生,讓內部作用域依然存在,不被**,讓bar()來使用。

bar()foo()執行結束後,依然保持對該作用域的引用,這就叫做閉包!

上面的**是不是十分眼熟?

function foo() , 1000)

}

這個定時器,是不是閉包?

定時器、事件***、ajax 請求、跨視窗通訊……只要用到了**函式,都是閉包!

for (var i = 0; i < 5; i++) , 1000 * i)

}

為什麼這個**每個一秒會輸出一次 5?

就算輸出也應該是 4 啊,為什麼呢?

因為 var 的 i,作用域其實在外面。最後一次結束的時候,i 已經是 5 了。

而非同步操作,都是在 for 迴圈結束之後才執行的。

也就是說,每次迴圈結束,都會記住settimeout(() => , n000),然後在 for 結束之後,統一的把 i 傳入 console。

那自然而然的,會都輸出 5 了。

那這個怎麼讓他每一次迴圈都能夠實現,console 對當前 i 的引用呢?這也是閉包呀。

把 settimeout 單獨放到乙個作用域裡,然後再迴圈的時候把當前的 i 傳進去就可以了!非常簡單!

for (var i = 0; i < 5; i++) , 1000 * j)

})(i)

}

成功了!

但實際上,如果使用 let,完全不會有這種需要「洩露」的情況。

(完)

非對稱加密,我終於理解了!

北京的bob發了乙個快遞到廣州的alice,途中經過了上海,上海快遞中心出現了乙個黑客h,他偷偷開啟了bob給alice的快遞,然後偷偷把裡邊的衣服剪爛,再按照原樣包裝好發往廣州,可以看到對於這樣簡單包裝的傳輸在中途是可以偷偷修改裡邊的東西。http的資料報是明文傳輸,也即是如果中途某個黑客嗅探到這...

我終於理解了JSP 的分頁了

我們查詢資料庫的時候 如果查詢出來的結果是很多條,比如 1000條,那麼,如果都顯示到乙個頁面上簡直是令人無法忍受的事情 所以我們要分頁顯示 每頁顯示10或 20行 分頁的目的就這樣簡單 分頁的方法有很多種 也許有些效率要高些 我這裡只能參考最簡單能實現的方法 現查找出有多少條記錄 然後計算出一共分...

終於理解了什麼是LGPL

我 們很熟悉的linux 就是採用了gpl。gpl協議和bsd,apache licence等鼓勵 重用的許可很不一樣。gpl的出發點是 的開源 免費使用和引用 修改 衍生 的開源 免費使用,但不允許修改後和衍生的代 碼做為閉源的商業軟體發布和銷售。這也就是為什麼我們能用免費的各種linux,包括商...