js中使用一個變量之前應當先聲明。變量使用關鍵字var來聲明。
如果未在var聲明語句中給變量指定初始值,則該變量值為undefined。
不用在聲明變量時指定變量類型,js變量可以是任意資料類型。
使用var語句重複聲明變量是合法且無害的。如果重複聲明帶有初始化器,則就和簡單的指派語句沒啥差別。
如果試圖讀取一個沒有聲明的變量,則js會報錯。在ecmascript5嚴格模式下,給一個沒有聲明的變量指派也會報錯;然而從曆史上來說,在非嚴格模式下,如果給一個未聲明變量指派,js實際上會給全局對象建立一個同名屬性,且貌似它工作起來像一個正确聲明的全局變量。這意味着你可以僥幸不聲明全局變量,但這是一個壞習慣會造成很多bug,最好始終使用var來聲明變量。
在函數體内,同名的局部變量會覆寫全局變量。
盡管全局作用域寫代碼可以不寫var語句,但聲明局部變量時必須使用var語句,參考如下代碼:
在類似c語言的程式設計語言中,花括号中每一段代碼都有各自的作用域,且變量在聲明它們代碼段之外是不可見的,我們稱之為塊級作用域(block scope);而js中沒有塊級作用域,而是取而代之的使用了函數作用域(function scope):變量在聲明它們的函數體以及這個函數體嵌套的任意函數體内都是有定義的(無論是内嵌套還是外嵌套?)
js的函數作用域指在函數内聲明的所有變量在函數體内始終是可見的,這意味着變量在聲明前甚至可以使用了。js的這個特性非正式的稱為聲明提前(hoisting),即js函數裡聲明的所有變量(但沒有指派)都被“提前”至函數體的頂部。
以上代碼等價于:
當聲明一個js全局變量時,實際上定義了全局對象的一個屬性。
當用var聲明一個變量時,建立的這個屬性時不可配置的,即無法用delete運算符删除;但當你沒有使用嚴格模式并給一個未聲明的變量指派的話,js會自動建立一個全局變量,以這種方式建立的變量是全局對象的正常可配置屬性,是可以删除的: