js變量的聲明、作用域以及閉包

1、變量的聲明

  • 使用var多次聲明同一個變量,是合法的,不會因此語法的錯誤;重複的聲明並初始化變量值,只是相當於普通的賦值語句。
  • 讀取一個未聲明的變量值,js會產生一個錯誤。
  • 嘗試給一個未經var 聲明的變量賦值,js會隱式聲明該變量,隱式聲明的變量被創建爲全局變量。
  • 無論是全局變量還是局部變量,最好都使用var進行聲明。
  • 如果在var中沒有初始化變量的值,則默認爲undefined.
  • 當要聲明一個變量並進行初始化,但又不想指定任何特殊值,可以賦值爲 JScript 值 null。比如:var bestAge = null;
  • 在 JScript 中 null 和 undefined 的主要區別是 null 的操作象數字 0,而 undefined 的操作象特殊值NaN (不是一個數字)。對 null 值和 undefined 值作比較總是相等的。
  • 要想顯式地將字符串轉換爲整數,使用 parseInt 方法。要想顯式地將字符串轉換爲數字,使用 parseFloat 方法。請注意,比較大小時字符串自動轉換爲相等的數字,但加法(連接)運算時保留爲字符串。

2、變量的作用域

全局(global)變量的作用域是全局的,即在js代碼中處處有定義。

局部(local)變量的作用域是局部性的,只在特定的範圍內,比如函數內部定義的變量,函數的參數變量,這些變量的作用範圍是侷限在函數的內部的。

1.聲明全局變量可以不適用var 關鍵字,局部變量則必須使用var關鍵字來聲明,爲了避免不必要的麻煩,養成所有的變量都使用var關鍵字來聲明。

2.變量的定義沒有塊級作用域

例:

			function fn() {
					alert(fag);     //提示undefined
					var fag = 'green';
					alert(fag);		//提示green
				}


問:第一次alert提示fag undefined ,而我們又定義了全局變量fag?????

解析:由於變量的定義沒有塊級作用域這個規則的限制,局部變量在整個函數內部都是有定義的,這就意味着整個函數體中都隱藏了同名的全局變量,

   第一次alert, 局部變量fag是已經被聲明瞭,但是沒有初始化值,所以提示undefined;

   而第二次的alert,是在 = "green" 之後的,也就是局部變量fag完成了初始化,所以提示爲green。

     該例子中的代碼相當於

			function fn() {
				var fag;           //聲明局部變量fag, 沒有初始化
				alert(fag);
				var fag = 'green'; //初始化fag
				alert(fag);
			}

3、未定義的變量和未賦值的變量

未定義的變量:指沒有聲明並且沒有初始化的變量,嘗試讀取這種變量會產生一個錯誤。

     注 : 這裏要區分開沒有聲明但初始化了的變量,這種變量不會引起錯誤,程序會在全局變量中隱式的聲明該類變量。

未賦值的變量:指已經聲明但沒有初始化的變量,嘗試讀取該類變量將得到一個默認值undefined.

4、閉包

     要理解閉包,首先必須理解Javascript特殊的變量作用域。

     變量的作用域無非就是兩種:全局變量局部變量

     Javascript語言的特殊之處,就在於函數內部可以直接讀取全局變量。另一方面,在函數外部自然無法讀取函數內的局部變量。這裏有一個地方需要注意,      函數內部聲明變量的時候,一定要使用var命令。如果不用的話,你實際上聲明瞭一個全局變量!

     出於種種原因,我們有時候需要得到函數內的局部變量。但是,前面已經說過了,正常情況下,這是辦不到的,只有通過變通方法才能實現。

     那就是在函數的內部,再定義一個函數。

			function fn1() {
					var n=999;				
					
					function fn2 () {
						alert(n);//999
					}
				}

     在上面的代碼中,函數fn2就被包括在函數fn1內部,這時fn1內部的所有局部變量,對fn2都是可見的。但是反過來就不行,fn2內部的局部變量,對fn1 就      是不可見的。這就是Javascript語言特有的“鏈式作用域”結構(chain scope),

     子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。

     既然fn2可以讀取fn1中的局部變量,那麼只要把fn2作爲返回值,我們不就可以在fn1外部讀取它的內部變量了嗎! 

			function fn1() {
					var n=999;				
					
					function fn2 () {
						alert(n);
					}
					return fn2;
				}
				var result = fn1();
				result();//999

     上面代碼中的fn2函數,就是閉包。

     各種專業文獻上的“閉包”(closure)定義非常抽象,很難看懂。我的理解是,閉包就是能夠讀取其他函數內部變量的函數。

     由於在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成“定義在一個函數內部的函數”。

     所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋樑。 





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章