與C、Java等編程語言不同,JavaScript中的變量是無類型的,所有的變量定義使用的關鍵詞均為var:
復制代碼 代碼如下:
var a;
var m, n;
var x=42, y="test";
如果定義變量後未對該變量進行賦值,那麼該變量的值為undefined。如上面代碼中的a、m、n三個變量的值均為undefined。
由於JS中變量是無類型的,因此完全可以對同一個變量進行不同類型的賦值,如:
復制代碼 代碼如下:
var b = "temp";
console.log(typeof b);//string
b = 108;
console.log(typeof b);//number
除了可以對同一變量進行不同類型的賦值,JavaScript中還可以對變量進行重復定義;如果這麼做,則第一次之後的變量定義語句等價於賦值語句:
復制代碼 代碼如下:
var c = "hello";
console.log(c);//hello
var c = true;
console.log(c);//true
在ECMAScript標准的嚴格模式(strict mode)下,所有的變量定義均需使用var關鍵詞。如果不使用嚴格模式,那麼當JS程序對某個未被定義過的變量進行賦值時,程序將在JS全局對象中創建一個名稱與該變量相同的屬性,也即創建一個新的全局變量。這種做法會帶來很多問題(比如,多個JS程序間產生全局變量污染等),給後期維護帶來不小的麻煩;因此在實際開發過程中,應當盡量避免使用這種做法。
變量的儲存
如果定義的變量為全局變量,同時在變量定義過程中沒有使用var關鍵詞,那麼該變量會作為全局對象的屬性而存在,可以通過訪問this(全局對象)的相應屬性而獲得,也可以通過使用delete關鍵詞將其從全局對象中刪除掉:
復制代碼 代碼如下:
var e = "globalVariableValue";//defined outside of any function, it is a global variable, but does not store in "this"
f = "globalVariableValue2";
this.g = "globalVariableValue3";
console.log(this.e);//undefined
console.log(this.f);//globalVariableValue2
console.log(this.g);//globalVariableValue3
delete f;
delete g;
console.log(this.f);//undefined
console.log(this.g);//undefined
對於JavaScript中的每一次函數調用,JavaScript都會創建一個局部對象以儲存在該函數中定義的局部變量;如果在該函數內部還有一個嵌套定義的函數(nested function),那麼JavaScript會在已經定義的局部對象內部再定義一個嵌套局部對象。對於一個函數,其內部有多少層的嵌套函數定義,也就有多少層的嵌套局部對象。該局部對象稱為“函數調用對象”(ECMAScript 3中的“call object”,ECMAScript 5中改名為“declarative environment record”,但個人認為還是ECMAScript 3中的名稱更容易理解一些)。
與全局對象this相反,JavaScript中不提供任何方式來訪問這些局部對象(函數調用對象)。因此,開發人員無法對這些局部對象進行操作。不過,理解這些函數調用對象對於理解JavaScript中的一些概念會有很大的幫助,比如說變量的作用域和閉包。