標籤:報錯 bbb 刪除 導致 分享 過程 原來 foo 空間
閉包
是指在一個函數中聲明一個函數,在外部函數結束的時候返回內建函式的引用,那麼在執行外部函數的時候就會
產生一個內建函式的引用,因為外部函數執行完成,理論上外部函數的ao的引用是應該被刪除或者說釋放的。
但因為有了內建函式的引用,這個內建函式在聲明的時候就已經指向了外部函數的ao以及go,所以,即使外部函數
ao的引用已經釋放,由於內建函式被儲存在了外部,導致外部函數申明與執行所產生的ao被保留下來。
<body> <script type="text/javascript"> function a(){ function b(){ var bbb = 234; consloet.log(aaa); };
var a = 123 return b; } var golb = 100; var demo = a(); demo();</script></body>
此例的輸出結果是:123
按原來的理解,b函數中是沒有a這個變數的,正常如果沒有外部的a函數,就會報錯 a is not define
但是這裡,由於在a執行完的時候,把b的引用儲存在了函數a之外,而b這個函數在聲明的時候,它的scope chain仍然和a執行是同一個,
即:0:aAO;1:GO,就是把a中的執行內容儲存在了b函數中。在執行函數b的時候回產生一個bAO放在scope chain的0位置,執行完的
時候刪除這個bAO,而在1、2位置的0:aAO;1:GO被永久的保留了下來。
aAO中是由a = 123這個變數的,故而最終的結果是列印出a的值!~
這 就是閉包!
**注意點**------當內建函式被儲存到外部時,將會產生閉包。閉包會導致原有scope chain(範圍鏈)不釋放,造成記憶體流失
記憶體流失:由於記憶體一直佔用,導致可用記憶體空間減小,感覺就像記憶體流失了一樣,就叫記憶體流失了~~!會導致載入非常慢!!
scope chain 中的沒產生一個新的ao,必然繼承外部函數產生的ao與go,這裡的繼承是指指向了原來那個AO、GO,而不是產生一個一模一樣的
ex:
<body> <script type="text/javascript"> function text(){ var num = 100; function b(){ num ++; console.log(num); } function b(){ num --; console.log(num); } return [a,b]; } var myArr = text(); myArr[0](); myArr[1]();</script></body>
輸出的結果是:101 100
而不是101 99,注意其中的區別!
所以再修改來自外部函數的ao時,是修改的同一個AO
ex:
<body> <script type="text/javascript"> function a(){ var num = 100; function b(){ num ++; console.log(num); } return b; } var demo = a(); demo(); demo();</script></body>
此例的結果是:101
102
有累加的效果
閉包的作用:1實現共有變數----->函數累加器
2可以做緩衝(儲存結構)----->eater
3可以實現封裝,屬性私人化------>Person();
4模組化開發,防止汙染全域變數
ex: 實現共有變數----->函數累加器
<body> <script type="text/javascript"> function add(){ var count = 0; function demo(){ count ++; consloet.log(count); }; return demo; } var counter = add(); counter(); counter(); counter(); counter(); counter(); counter(); counter(); counter(); </script></body>
輸出結果: 1 2 3 4 5 6 7
ex:可以做緩衝(儲存結構)----->eater 3
<body> <script type="text/javascript"> function eater(){ var food = ""; var obj = { eat : function(){ console.log("i am eating!" + food); food = ""; }, push : function(myfood){ food = myfood; } } return obj; } var demo = a(); erter1.push(‘banana‘); eater1.eat();</script></body>
輸出結果; i am eating banana
其中實際有兩個過程,一個把banana放入myfood,第二個過程才是列印 i am eating banana
javascript 閉包及其解決