關於Javascript閉包與應用的詳解
前言
Javascript閉包在學習過程中一般較難理解,本文從什麼是閉包,常見閉包示例,閉包作用,閉包應用及閉包問題等方面來介紹閉包,希望能給大傢帶來更深層次的認識,有不恰當之處請指出,謝謝。
一、什麼是閉包?
閉包是指一個嵌套的內部(子)函數引用瞭父函數作用域中數據的函數,這就產生瞭閉包。
關鍵理解:
1. 產生閉包必須要有嵌套函數
2. 閉包是函數,並是嵌套的內部函數
3. 閉包內部函數必須要引用父函數作用域中數據
如果不滿足以上條件,則不能產生閉包,接下來示例說明。
1.1閉包滿足條件代碼
<script> function person(){ var name='marshal'; function student(){ //聲明子函數 console.log(name);//引用父函數作用域的變量name } } person();//函數執行,產生閉包 </script>
1.2閉包產生時機
<script> function person(){ var name='marshal';//js執行此行時,產生閉包 function student(){ //聲明子函數 console.log(name);//引用父函數作用域的變量name } student();//內部函數在外部函數調用 } person();//函數執行,雖滿足閉包條件,但未產生閉包 </script>
閉包產生時機:嵌套子函數代碼塊有引用父函數作用域的數據,並該嵌套子函數要執行前,創建上下文時產生閉包。或者簡單說該該嵌套子函數在外部被執行時,此刻產生瞭閉包。
<script> function person(){ var name='marshal'; function student(){ console.log(name); //該方法代碼內為閉包代碼 } return student; } var p=person();//因創建子函數對像,此時產生第一次閉包,並將子函數student返回給p,由於p沒有消失,子函數引用的變量name,一直在內存在存儲,直到將p=null,進行回收 p();//執行子函數的閉包代碼塊,輸出"marhsal" p();//第二次執行子函數的閉包代碼塊,輸出"marhsal" person();//第二次創建子函數調對象,此時產生第二次閉包,但不執行子函數student代碼塊 </script>
二、常見閉包示例
2.1 子函數做為實參傳遞
<script> function setTimeoutTest(message,time){ setTimeout(function(){ alert(message);//嵌套子函數引用父函數變量message,產生閉包 },time); } setTimeoutTest('提示信息',1000); </script>
2.2 計數器使用(函數返回)
<script> function count(){ var i=1; function add(){ i++; console.log(i); } return add; } var c=count();//生產閉包 c();//2 c();//3 c();//4 </script>
三、閉包作用
3.1 閉包作用
1)子函數引用父函數的變量或函數,生命周期延長
2)其變量或函數一直存在,外部可以訪問函數內部的值
<script> function count(){ var i=1; function add(){ i++; console.log(i); } return add; } var c=count(); c();//2 c();//3 i的生命周期延長 </script>
四、閉包應用
4.1 自定義封裝js代碼
外部js代碼 out.js 實現自加與自減 (function count(){ var i=1; function add(){ i++; console.log(i); } function subtract(){ i-- console.log(i); } window.count={ add:add, subtract:subtract } })();
引用 out.js代碼 <script src=out.js></script> <script> count.add(); //2 count.subtract();//1 count.subtract();//0 </script>
五、閉包問題
5.1 閉包與this
<script> var name="marshal"; //創建全局變量 var person={ name:"leo", getName:function(){ //返回匿名函數 return function(){ //返回this.name return this.name; //返回字符串 } } }; alert(person.getName()()); //輸出marshal,內部函數不可能直接訪問外部函數this </script>
解決方法
<script> var name="marshal"; var person={ name:"leo", getName:function(){ var that=this;//把this保存到閉包可以訪問的另一個變量中 return function(){ return that.name; } } }; alert(person.getName()());//that 指向person,而不是window </script>
5.2 內存泄露
在使用閉包時,因變量一直存在,需要解除對象的引用,將對象設置為null, 從而確保其內存在適當時候可以被回收。
到此這篇關於關於Javascript閉包與應用的詳解的文章就介紹到這瞭,更多相關js閉包與應用內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- None Found