對js中區域性變數、全域性變數和閉包的理解
對js中區域性變數、全域性變數和閉包的理解
區域性變數
對於區域性變數,js給出的定義是這樣的:在 JavaScript函式內部宣告的變數(使用 var)是區域性變數,所以只能在函式內部訪問它。(該變數的作用域是區域性的)。可以在不同的函式中使用名稱相同的區域性變數,因為只有宣告過該變數的函式才能識別出該變數。只要函式執行完畢,本地變數就會被刪除。
我們先來逐步理解:
只能在函式內部訪問
function test() { var a = 0; return a; } console.log(a); //結果:a is not defined
上面的程式碼聲明瞭一個test()函式,在函式內部聲明瞭一個區域性變數a,當我們嘗試在函式外訪問區域性變數a時,出來的結果是
a is not defined
我們再來看下面這個例子:
function test() { var a = 0; return a; } console.log(test()); //結果:0
以上兩個例子很好的闡述了局部變數只能在函式內部訪問,當呼叫函式時,函式域自動執行其中的程式碼,區域性變數自然也被呼叫。
只要函式執行完畢,本地變數就會被刪除
function b() { var y = 0; z = ++y; console.log("這是區域性變數y:",z) return z; } console.log(b(),b(),b()); //結果:這是區域性變數y: 1 //這是區域性變數y: 1 //這是區域性變數y: 1 //1 1 1
從上面程式碼我們可以看出,我們執行了3次函式呼叫,得到的結果都是1,可能有人會說,這很簡單啊,每次出來的結果都是1,那是因為每次執行函式,函式內都會將區域性變數y初始化為0。沒錯,的確是這樣,但是如果不初始化變數,則得到的返回值是
NaN
,所以初始化是必要的。所以,無論用什麼辦法,在函式內部用一個區域性變數去做累加,是不可能實現的。但是,我們可以通過全域性變數和閉包來實現累加。
全域性變數
在js中,這樣定義全域性變數, 在函式外宣告的變數是全域性變數,網頁上的所有指令碼和函式都能訪問它。 全域性變數會在頁面關閉後被刪除。
我們再來看一個例子
var a = 0; function b() { ++a; console.log("這是全域性變數a",a); return a; } console.log("這是未改變的全域性變數a:",a,"這是函式b():",b(),b(),b(),"這是改變後的全域性變數a:",a); //結果:這是全域性變數a 1 //這是全域性變數a 2 //這是全域性變數a 3 //這是未改變的全域性變數a: 0 這是函式b(): 1 2 3 這是改變後的全域性變數a: 3
上面程式碼定義了一個全域性變數a,和一個b()函式,通過函式內部對a執行自加加,實現了累加目的,通過三次呼叫函式,得到的結果a為3。
閉包
什麼是閉包呢?閉包的定義是這樣的,閉包是一種保護私有變數的機制,在函式執行時形成私有的作用域,保護裡面的私有變數不受外界干擾。直觀的說就是形成一個不銷燬的棧環境。
我對閉包的理解是這樣的,閉包就是一個內嵌函式引用頂層函式的變數,而頂層函式是一個立即執行函式(自呼叫函式),因為它會自動呼叫,所以區域性變數不會被刪除,但是這會增加記憶體消耗。
來看一個例子
function a() { var b = 0; return function() { return ++b; } } var closure = a(); console.log("這是閉包:",closure(),closure(),closure()); //結果:這是閉包: 1 2 3
我們看到,由於閉包的特殊機制,使得區域性變數在函式執行完之後不會被銷燬,由此得到的最後結果為3 ,而不是1。