1. 程式人生 > >深入理解javascript原型和閉包(12)——閉包

深入理解javascript原型和閉包(12)——閉包

執行環境 分享圖片 script com 活動 時有 mage ava 五步

閉包的官方定義時有權訪問另一個函數作用域中的變量的函數。

閉包有兩種用法:函數作為返回值,函數作為參數傳遞

第一:函數作為返回值

技術分享圖片

上面代碼中,bar函數作為fn函數的返回值,賦值給了變量f1,因此執行f1()就是執行bar函數,執行bar函數時,變量max從fn作用域中去取。

第二:函數作為參數傳遞

這種一般是自執行的匿名函數

技術分享圖片

上面代碼中,fn函數作為參數賦值給自執行匿名函數裏的f參數,因此執行f(15)就是執行fn(15),執行fn(15)時,max的值取全局作用域中的10。

另外,閉包的另一個作用就是可以讓變量常駐內存,一般而言函數執行完,該函數的執行環境應該被銷毀,但由於閉包的存在,函數的執行環境不會立即被銷毀。

技術分享圖片

上面代碼中,第一步,代碼執行前生成全局執行環境,並在其中對變量進行賦值,此時全局執行環境處於活動狀態。

第二步,執行第17行代碼,fn函數作為變量賦值給了f1變量,調用fn(),產生了fn函數的執行環境,此時fn執行環境處於活動狀態

第三步,執行完17行代碼,按理說應該銷毀fn函數的執行環境,但此時不能這麽做,因為,執行fn函數時,返回的是一個函數。而函數的特別之處在於可以創建一個獨立的作用域。

並且bar函數體中,還有一個自由變量要引用fn作用域中的值。因此fn執行環境不能被銷毀,毀了之後max就找不到值了。

第四步,執行18行代碼,此時全局執行環境和fn執行環境都處於活動狀態,執行完18行代碼,全局執行環境中的max變量被賦值為100

第五步,執行20行代碼,因為17行代碼中fn函數被賦值給了f1變量,因此執行f1函數就是執行fn函數,即執行bar函數,此時bar函數處於活動狀態。

執行bar函數時,max是自由變量,需要到創建bar函數的作用域中去查找,因此找到了fn作用域,即max的值為10。

從這裏可以看出,創建bar函數是在執行fn函數時創建的。fn早就執行完了,但fn的執行環境依然存在於內存中,因此執行bar(15)時,max可以查找到,如果fn執行環境銷毀了,那max就找不到了。

結論:使用閉包,會增加內存消耗。

如果使用不當,還會造成內存泄漏問題。

深入理解javascript原型和閉包(12)——閉包