對於局部變量,js給出的定義是這樣的:在 JavaScript函數內部聲明的變量(使用 var)是局部變量,因此只能在函數內部訪問它。(該變量的做用域是局部的)。能夠在不一樣的函數中使用名稱相同的局部變量,由於只有聲明過該變量的函數才能識別出該變量。只要函數運行完畢,本地變量就會被刪除。閉包
咱們先來逐步理解:函數
只能在函數內部訪問code
function test() { var a = 0; return a; } console.log(a); //結果:a is not defined
上面的代碼聲明瞭一個test()函數,在函數內部聲明瞭一個局部變量a,當咱們嘗試在函數外訪問局部變量a時,出來的結果是a is not defined
ip
咱們再來看下面這個例子:內存
function test() { var a = 0; return a; } console.log(test()); //結果:0
以上兩個例子很好的闡述了局部變量只能在函數內部訪問,當調用函數時,函數域自動執行其中的代碼,局部變量天然也被調用。作用域
只要函數運行完畢,本地變量就會被刪除io
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
,因此初始化是必要的。因此,不管用什麼辦法,在函數內部用一個局部變量去作累加,是不可能實現的。可是,咱們能夠經過全局變量和閉包來實現累加。console
在js中,這樣定義全局變量, 在函數外聲明的變量是全局變量,網頁上的全部腳本和函數都能訪問它。 全局變量會在頁面關閉後被刪除。function
咱們再來看一個例子class
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。