java 闭包_公司新来的女实习生问我什么是闭包?
作者:霍語佳
來源:前端食堂
觀感度:?????
口味:冰鎮西瓜
烹飪時間:20min
撩妹守則第一條,女孩子都喜歡童話故事。
那就先來講一個童話故事~
// 有一個公主// 她生活在一個充滿冒險的奇妙世界里// 她遇見了她的白馬王子,帶著她騎著獨角獸環游世界// 與龍搏斗,遇到了會說話的松鼠,以及許多其他幻想的事情。function princess () { var adventrures = []; function princeCharming () {}; var unicorn = {}; var dragons = []; var squirrel = "Hello!"; // 但她不得不回到她那充滿家務和大人們的單調世界。 return { // 她經常給身邊的人講她作為一個公主的奇妙經歷。 story:function () { return adventures[adventures.length - 1]; } }}// 但他們看到的只是一個小女孩在講述關于魔法和幻想的故事var littleGril = princess();littleGril.story();// 即使大人們知道她是真正的公主,他們也不會相信所謂的獨角獸或龍,因為他們永遠看不到它們// 大人們說它們只存在于小女孩的想象中// 但我們知道真正的真理// 里面的小女孩真的是個公主這個故事來自于stackoverflow的一則回答
stackoverflow的一則回答
https://stackoverflow.com/questions/111102/how-do-javascript-closures-work/111111#111111看不懂沒關系,等閱讀完本文后,回頭再來看這個故事,你會發現你已經完全了解了我的魅力,咳咳@¥%#…………JavaScript中閉包的魅力。
1
?什么是閉包?
當函數可以記住并訪問所在的詞法作用域時,就產生了閉包,即使函數是在當前詞法作用域之外執行。? ??--- 你不知道的JavaScript(上卷)
來個?
function demo() { var a = 1; return function () { return a; }}var a = demo();console.log(a()); // 12
?閉包的構成
閉包由兩部分構成:函數,以及創建該函數的環境。
環境由閉包創建時在作用域中的任何局部變量組成。
3
?閉包的本質
閉包其實是JavaScript函數作用域的副作用產品。
閉包是一種特殊的對象。
所謂有意栽花花不開,無心插柳柳成蔭,不是JavaScript故意要使用閉包,而是由于JavaScript的函數內部可以使用函數外部的變量,這段代碼又剛剛好符合閉包的定義。
在JavaScript中,外部函數調用之后其變量對象本應該被銷毀,但閉包阻止了它們的銷毀,我們仍然可以訪問外部函數的變量對象。
進一步的說,通常情況下,函數的作用域及其所有變量都會在函數執行結束后被銷毀。但是,如果創建了一個閉包的話,這個函數的作用域就會一直保存到閉包不存在為止。
function addCalculator (x) { return function (y) { return x + y; }}var add1 = addCalculator(1);console.log(add1(1)); //2// 釋放對閉包的引用add1 = null;console.log(add1(1)); //Uncaught TypeError: add1 is not a function4
?閉包的應用
我們可以用閉包來做什么呢?
了解Java的同學可能知道,Java是支持私有方法的,私有方法只能被一個類中的其他方法所調用,但是JavaScript沒有提供這種原生支持,所以我們可以通過閉包來模擬私有方法。
私有方法自然有私有方法的好處,私有方法有利于限制對代碼的訪問,而且可以避免非核心的方法干擾代碼的公共接口,減少全局污染。
來個?
var calculator = (function(){ var a = 1; function addCalculator(val){ a += val } return { add1:function() { addCalculator(1); }, add2:function() { addCalculator(2); }, result:function() { return a } }})();console.log(calculator.result()); // 1calculator.add1();console.log(calculator.result()); // 2calculator.add2();console.log(calculator.result()); // 4上面這種方式也叫做模塊模式(module pattern)。
5
?使用閉包的注意事項
內存泄漏
因為閉包可以使函數中的變量都保存在內存中,造成很大的內存消耗,所以如果不是某些特定的任務需要使用閉包,我們不要濫用它。
很多博客中都提到了這一點,但是其實都是不完全對的。
敲黑板!!!
使用不當的閉包會在IE(IE9)之前造成內存泄漏問題。因為它的JavaScript引擎使用的垃圾回收算法是引用計數法,對于循環引用將會導致GC(下文會介紹)無法回收垃圾。
關于各個瀏覽器的閉包測試,詳情請見:
司徒正美-js閉包測試
https://www.cnblogs.com/rubylouvre/p/3345294.html6
?垃圾回收機制
都9102年了,全國開始實行垃圾分類了,你居然還不知道垃圾回收機制,趕快來補習一下!
垃圾回收也就是GC(Garbage Collection)
GC把程序不用的內存空間視為垃圾,找到它們并且將它們回收,讓程序員可以再次利用這部分空間。
不是所有的語言都有GC,一般存在于高級語言中,如Java、JavaScript、Python。那么在沒有GC的世界里,程序員就比較辛苦,只能手動去管理內存,比如在C語言中我們可以通過malloc/free,在C++中的new/delete來進行管理。
7
?垃圾回收算法
因為這一部分的內容很多,本文只進行簡單的講解,如果想深入了解垃圾回收算法的同學可以在文末獲取學習資料。
GC標記-清除算法
世界上首個值得紀念的GC算法是GC標記-清除算法。因為自其問世以來,一直到半個世紀后的今天,它依然是各種處理程序所用的偉大的算法。
GC標記-清除算法由標記階段和清除階段構成,標記階段將所有的活動對象做上相應的標記,清除階段把那些沒有標記的對象,也就是非活動對象進行回收。在搜索對象并進行標記的時候使用了深度優先搜索,盡可能的從深度上搜索樹形結構。
優點:
1.算法簡單,實現容易。
2.與保守式的GC算法兼容。
缺點:
1.在使用過程中會出現碎片化的情況,如同Windows的文件系統一樣,導致無數的小分塊散布在堆的各個地方。
2.分配速度,由于分塊的不連續性,算法每次分配的時候都需要遍歷空閑鏈表為了找到足夠大的分塊,這樣最糟糕的情況就是遍歷到最后才找到合適的分塊,影響了分配速度。
引用計數法
這種方法中引入了計數器的概念,通過計數器來表示對象的“人氣指數”,也就是有多少個程序引用了這個對象。當計數器(引用數)為0時,垃圾立刻被回收。
優點:
1.可以立即回收垃圾。
2.最大暫停的時間短。
3.并且沒有必要沿指針查找。
缺點:
1.上文提到過的循環引用無法回收。
2.并且實現起來很復雜。
3.計數器值的增減處理十分繁重。
4.同時計數器需要占很多位,導致內存空間的使用效率大大降低。
軟件工程沒有銀彈,這些缺點也都有相應的辦法進行解決,如果你想深入了解垃圾回收算法,可以購買這本書去看,建議支持正版。
垃圾回收的算法與實現
https://book.douban.com/subject/26821357/https://book.douban.com/subject/26821357/●?程序員相親圖鑒,太真實了!
●?Vue3的到來,是不是意味著不學TypeScript不行了?
●?從小白到全棧CTO,十年經驗分享給大家
●?根據Git推算程序員大佬作息:同樣是熬夜,為什么他發量那么多?
Tips:
# 點下“在看”??
# 然后,留個言踩個樓?每月留言精選前五將有好禮相送哦
# 開獎日期:11月1號,獎品是精挑細選的技術書籍/專欄or慕課網精美周邊
總結
以上是生活随笔為你收集整理的java 闭包_公司新来的女实习生问我什么是闭包?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bootstrap jquery ale
- 下一篇: 徽商银行信用卡现金分期可以提前还款吗?手