變數的聲明
JavaScript 使用關鍵字 var 來聲明變數,可以先聲明後賦值,也可以在聲明的同時賦值,多個變數同時聲明使用逗號(,)分隔。例如:
代碼如下 |
複製代碼 |
// 先聲明,後賦值 var sex; sex="男"; // 聲明的同時進行賦值 var age=22; var name="張三"; // 同時聲明多個變數 var x=1,y=2,z=3; |
// 聲明多個變數時用逗號( ,)分開其中,sex、age、name ... 稱為 變數名,"男"、22、”張三 ... 稱為 變數值。
JavaScript 是弱類型的語言,聲明變數時無需聲明資料類型,JavaScript 會根據變數內容自動判斷資料類型。
JavaScript 變數命名規範:變數必需以 字母、$ 和 _ 開頭,不能以數字和其他字元開頭。
注意:JavaScript 是區分大小寫,變數 age 不等於 AGE 。
變數的使用
變數聲明以後,就可以使用了。
例如,聲明了兩個變數 x 和 y :
代碼如下 |
複製代碼 |
var x=2; var y=3;要想得到 x+y 的值,可以: var z=x+y; document.write(z);運行代碼,將輸出 5 。 |
Y:
未賦值變數
未賦值變數是指已經使用 var 關鍵字聲明,但是沒有賦值的變數。
在JavaScript中,未賦值變數有一個預設值,是 undefined ,即” 未定義 “。
例如:
代碼如下 |
複製代碼 |
var x; // x = undefined alert(x); |
運行代碼,彈出警告框,顯示 undefined 。
注意:未賦值變數不等於未聲明的變數。在JavaScript中,引用一個未賦值的變數,其值為 undefined ,引用一個未聲明的變數將會引發錯誤。
例如:
運行代碼,沒有彈出警告框,開啟 Chrome 調試工具(F12),可以看到引發了如下錯誤:
Uncaught ReferenceError: xyz is not defined
即“未捕獲的引用錯誤:xyz 沒有定義”。
這時有人可能會問,上述的兩種聲明有什麼區別,為什 麼會有這兩種不同的聲明方式,這就涉及到javascript中變數的範圍了。在javascript中,變數的範圍包括全域和函數層級的。
全域變數可以聲明在函數體外,無論使用上述的哪種聲明方式,在函數體外 聲明的變數都是全域變數。如:
代碼如下 |
複製代碼 |
<script type="text/javascript" language="javascript"> var v = 1; function foo() { alert(v); } w = 2; function bar() { alert(w); } foo(); </script> |
運行結果:1 2
另外,在函數內部聲明的變數如果不使用var關鍵字,聲明的變數也將是全域變數。如:
代碼如下 |
複製代碼 |
<script type="text/javascript" language="javascript"> function foo() { v = 1; } foo(); alert(v); </script> |
運行結果:1
但是需要注意,這種情況下,若要使用變數,必須先調用聲明變數的函數對變數進行初始化, 如foo(),否則,將會出現“變數v未定義”的錯誤。
全域變數將作為window對象的屬性存在,因為可以 通過window.$($表示變數名)訪問。當然也可以通過變數名直接存取。下面會講到為什麼有這兩種訪問方式。
在函數內部通過var關鍵字聲明的變數將是函數層級的變數,其範圍僅僅限於函數內部。如:
代碼如下 |
複製代碼 |
<script type="text/javascript" language="javascript"> function foo() { var v=1; alert(v); } alert(v); </script> |
運行結果:1 變數“v”未定義
通過上面的分析,可以發現關鍵字var主要作用 是定義函數層級的變數。
細心的朋友可以會問,如果在函數內部和外部定義了相同的變數,會是什麼樣的結果呢?如:
代碼如下 |
複製代碼 |
<script type="text/javascript" language="javascript"> var v=1; function foo() { alert(v); var v=2; } foo(); </script> |
運行結果:undefined
!!!!!也許有人會比較鬱悶了,v明明白白的定義在函數foo()體外,為什麼會是 undefined呢?這就涉及到javascript的解析了。根據經驗,javascript對於函數體內變數的解析過程是:
搜尋所有的 var關鍵字,將其變數聲明放到函數體的最前面,賦值和使用仍然保持不變,這樣,上面的javascript實際上是等同於:
代碼如下 |
複製代碼 |
<script type="text/javascript" language="javascript"> var v=1; function foo() { var v; alert(v); v=2; } foo(); </script> |
照此分析,產生上述 的結果就顯而易見了,由於函數內部的變數的優先順序高於全域變數的優先順序(大部分的程式設計語言都是這樣), 函數內部的變數v覆蓋了全域變數v,但是由於在使用函數內部變數v時,它僅僅聲明,但未賦值,因此結果是undefined。
如果在方法 體內仍然要使用定義的全域變數v,window對象此時派上大大的用場了,可以通過window.v來訪問。如:
代碼如下 |
複製代碼 |
<script type="text/javascript" language="javascript"> var v=1; function foo() { alert(window.v); alert(v); var v=2; } foo(); </script> |
運行結果:2 undefined
變數的範圍
JS中變數的範圍分為全域變數和局部變數,函數內定義的稱為局部變數,函數外的稱為全域變數。(“函數外的稱為全域變數”是相對的,另此處討論的前提是用var顯式聲明的變數,函數內不用var定義的變數預設是全域變數,當然忽略var聲明變數是不贊成的)。
代碼如下 |
複製代碼 |
var glob = 4;//函數外聲明全域變數 function fun() { var height = 20; //函數內用var聲明的是局部變數 weight = 50; //函數內不用var聲明的是全域變數 } fun(); alert(weight); |
JS中沒有塊級範圍,即用大括弧{}包含的。Java中則有。在main方法中寫入下代碼:
代碼如下 |
複製代碼 |
public static void main(String... args) { for(int i=0;i<5;i++) { } { int j=10; } int z = 20; System.out.println(i); // i不可見,文法分析時報錯,即編譯不通過 System.out.println(j); // j不可見,文法分析時報錯,即編譯不通過 System.out.println(z); // z可見,輸出20 } |
但如果在JS:
代碼如下 |
複製代碼 |
for(var i=0;i<5;i++) { } var obj = {name:"Lily"}; for(var attr in obj) { } { var j=10; } alert(i);//輸出4,沒有塊級範圍 alert(attr); //輸出name,沒有塊級範圍 alert(j);//輸出10,沒有塊級範圍 |
這也說明一個問題,避免在全域範圍內使用for迴圈同時聲明變數,否則會造成全域命名範圍的汙染。
當然,JS1.7中提出了let關鍵字聲明變數(見https://developer.mozilla.org/cn/New_in_JavaScript_1.7),只作用於for語句範圍。
代碼如下 |
複製代碼 |
for(let i=0;i<5;i++) { //todo } alert(i);//運行時報錯,提示i未定義 |
JS1.7需要這樣引用 <script type="application/javascript;version=1.7"/></script>
ps:firefox2+實現了JS1.7