閉包工作原理


閉包(Closure)是JavaScript語言中一個非常重要的特性

在Javascript語言中,只有函數中的子函數才能引用函數中的變量,簡單來說,閉包就是定義在函數中的函數,是函數內外部連接的橋梁

閉包的意義是:當前作用域總是能夠訪問外部作用域中的變量;函數是唯一擁有自身作用域的結構,所以閉包的創建依賴於函數

 

變量的作用域

閉包是Javascript語言中的一個難點,理解閉包之前,先來理解一下變量的作用域

全局變量、局部變量是變量的作用域僅有的兩種形態;一般來說,全局變量可以在任意作用域中引用,而局部變量則只能在當前作用域中引用。先看如下代碼所示

var number = 1;
var Get_Number = function ()
{
	console.log(number);
};
Get_Number();

輸出結果為1;這是一個全局變量,可以在任意作用域中引用。再看如下代碼所示

var Get_Number = function ()
{
	var number = 1;
};
console.log(number);

var Get_Number = function ()
{
	var number = 1;
};
Get_Number();
console.log(number);

輸出結果都為ReferenceError: number is not defined;這是一個局部變量,無法在外部作用域中引用該變量,運行該函數后也不能;這里需要注意的是,局部變量的聲明必須使用var表達式,否則運行該函數后相當於聲明了一個全局變量。代碼如下所示

var Get_Number = function ()
{
	number = 1;
};
Get_Number();
console.log(number);

輸出結果為1;這里實際上是聲明了一個全局變量

 

引用局部變量

正常來說,局部變量只能在函數中引用。先看如下代碼所示

var Get_Number = function ()
{
	var number = 1;
	var Out_Number = function ()
	{
		console.log(number ++);
	};
	Out_Number();
};
Get_Number();

輸出結果為1;子函數可以引用當前作用域中的變量,這實際上是JavaScript語言中的一個特色結構——作用域鏈(Scope Chain)。既然子函數可以引用該變量,那么我們return子函數,是不是就可以在外部作用域中引用該變量了。代碼如下所示

var Get_Number = function ()
{
	var number = 1;
	var Out_Number = function ()
	{
		console.log(number ++);
	};
	return Out_Number;
};
var r = Get_Number();
r();

輸出結果為1;並且我們繼續運行r(),輸出值會遞增——2、3、4、5,這個值被存儲於內存中,這個Out_Number子函數正是我們要討論的閉包

 

閉包的使用

閉包的兩大作用,一個是讀取函數中的變量,另外一個是將函數中的變量的值存儲於內存中。先看如下代碼所示

var Get_Number = function ()
{
	var number = 1;
	return {
		plus: function ()
		{
			number ++;
		},
		out: function ()
		{
			return number;
		}
	};
};

var r = Get_Number();
r.plus();
r.out();

返回值為2;2個閉包plus、out都維持着對Get_Number外部作用域的引用,在當前作用域中,只能通過這2個閉包訪問Get_Number外部作用域。代碼如下所示

var Get_Number = function ()
{
	var number = 1;
	return {
		plus: function ()
		{
			number ++;
		},
		out: function ()
		{
			return number;
		}
	};
};

var r = Get_Number();
r.change = function ()
{
	number = 0;
};
r.change();
r.plus();
r.out();

返回值同上;r.change並沒有改變Get_Number外部作用域中的變量number的值,它作用僅僅是聲明或者覆蓋了全局變量number

 

閉包可以在函數外部改變函數中的變量的值,如果你把函數作為對象、閉包作為方法、局部變量作為私有屬性使用,則會改變該變量的值;閉包還會把函數中的變量的值存儲於內存中,對內存消耗很大,所以濫用閉包的結果就是影響網頁性能,IE中則可能導致內存泄露


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM