關於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