[1]定義 [2]命名規則 [3]變數聲明 [4]變數特性 [5]變數作用域 [6]聲明提升(hoisting) [7]屬性變數 ...
×
目錄
[1]定義 [2]命名規則 [3]聲明[4]特性[5]作用域[6]聲明提升[7]屬性變數前面的話
關於javascript,第一個比較重要的概念是變數,變數的工作機制是javascript的基本特性。實際上,變數是標識符的一種。本文將詳細介紹變數和標識符
定義
標識符(Identifier)就是一個名字,用來對變數、函數、屬性、參數進行命名,或者用做某些迴圈語句中的跳轉位置的標記
//變數 var Identifier = 123; //屬性 (new Object).Identifier = 'test'; //函數及參數 function IdentifierName(Identifier1){}; //跳轉標記 Identifier: for(var i = 0; i < 5; i++){ if(i == 3){ break Identifier; } }
在日常生活中,有些東西是固定不變的,有些東西則會發生變化。例如,人的姓名和生日是固定不變的,但心情和年齡卻會隨著時間變化而變化。人們把那些會發生變化的東西稱為變數
當程式需要將值保存起來以備將來使用時,便將其賦值給一個變數。變數(variable)是一個用於保存值的占位符,可以通過變數名稱來獲得對值的引用
命名規則
在詞法結構一文中,我們介紹到javascript是一門區分字母大小寫的語言,且和其他任何編程語言一樣,javascript保留了一些標識符為自己所用,保留字不能用做普通的標識符
[註意]保留字包括關鍵字、未來保留字、空字面量和布爾值字面量
保留字 ReservedWord ::
Keyword
FutureReservedWord
NullLiteral
BooleanLiteral
javascript標識符名允許包含字母、數字、美元符號和下劃線(但第一個字元不允許是數字)
//錯誤示範 6num //開頭不能用數字 %sum //開頭不能用除(_ $)外特殊符號,如(% + /等) sum+num //開頭中間不能使用除(_ $)外特殊符號,如(% + /等)
javascript允許標識符中出現 Unicode字元全集中的字母和數字(包括中文)。因此,程式員也可以使用非英語語言或數學符號來書寫標識符
var 測試文字 = 'test';
[註意]出於可移植性和易於書寫的考慮,通常我們不使用擴展的ASCII或Unicode字元
通常駝峰格式是標識符命名的首選格式,第一個字母小寫,剩下的每個單詞的首字母大寫
var myMoodToday = 'happy';
對於不同的數據類型,javascript有約定俗成的標識符名命名規則
類型 首碼 示例
數組(Array) a aItems
布爾值(Boolean) b bIsComplete
浮點數(Float) f fPrice
函數(Function) fn fnHandler
整數(Integer) i iItemCount
對象(Object) o oDIv1
正則表達式(RegExp) re reEmailCheck
字元串(String) s sUserName
變數()Variant v vAnything
變數聲明
聲明
在javascript中,使用一個變數之前應當先聲明(declare),變數是使用關鍵字var(variable的縮寫)來聲明的
var i; var sum;
也可以通過一個var關鍵字來聲明多個變數
var i ,sum;
賦值
把值存入變數的操作稱為賦值(assignment)。一個變數被賦值以後,我們就說該變數包含這個值
給變數第一次賦值的過程,叫初始化
我們可以將變數的初始賦值和變數聲明合寫在一起
var message = 'hello'; var i=0,j=0,k=0;
如果未在var聲明語句中給變數指定初始值,那麼雖然聲明瞭這個變數,但在給它存入一個值之前,它的初始值就是undefined
在for迴圈和for-in迴圈中同樣可以使用var語句,這樣可以更簡潔地聲明在迴圈語法內中使用的迴圈變數
for(var i=0; i<10; i++)console.log(i);
變數可以在聲明時賦值,但不能有其他操作,如+=、-=等
var a = 2;//是正確的 var a += 2;//是錯誤的 var a = 2++;//是錯誤的,++只能用於變數,不能用於常量
重覆聲明
使用var語句重覆聲明變數是合法且無害的,如果重覆聲明且帶有賦值操作,相當於重新賦值
遺漏聲明
如果試圖讀取一個沒有聲明的變數的值,javascript會報錯
javascript允許遺漏聲明,即直接對變數賦值而無需事先聲明,賦值操作將自動聲明該變數 但是,在ECMAScript5嚴格模式中,給一個沒有聲明的變數賦值會報錯<script> 'use strict'; a = 5; console.log(a); </script>
變數特性
javascript變數是弱類型(也叫鬆散類型)的,所謂鬆散類型就是可以用來保存任何類型的數據
編程語言分類動態類型語言和靜態類型語言兩種。 動態類型語言是指在運行期間才去做數據類型檢查的語言,也就是說,在用動態類型的語言編程時,不用給任何變數指定數據類型,該語言會在第一次賦值給變數時,在內部將數據類型記錄下來。javascript就是動態類型語言的代表。
在javascript中,可以在修改變數值的同時修改值的類型
var message = 'hi'; message = 100;//有效,但不推薦
變數鬆散類型的特性總結起來有兩點:一是聲明時不用給變數指定數據類型;二是賦值時可以修改數據類型
變數作用域
變數的作用域(scope),又叫執行環境(execution context),是程式源代碼中定義這個變數的區域
作用域分為全局作用域和函數作用域(又叫局部作用域)兩種
全局作用域是最外圍的一個執行環境,在web瀏覽器中,全局執行環境被認為是window對象。所有全局變數和函數都是作為window對象的屬性和方法創建的。全局變數擁有全局作用域,在javascript代碼中的任何地方都是有定義的。全局作用域直到應用程式退出例如關閉網頁或瀏覽器時才會被銷毀
在函數內聲明的變數只在函數體內有定義。它們是局部變數,作用域是局部性的。函數參數也是局部變數,它們只在函數體內有定義。函數作用域中的所有代碼執行完畢後,該作用域被銷毀,保存在其中的所有變數和函數定義也隨之銷毀
function test(){ var message = 'hi'; } test(); alert(message);//錯誤
如果省略var操作符,則會創建一個全局變數
function test(){ message = 'hi'; } test(); alert(message);//'hi'
雖然省略var操作符可以定義全局變數,但並不推薦。在局部作用域中定義的全局變數很難維護,而且如果有意地忽略了var操作符,也會由於相應變數不會馬上就有定義而導致不必要的混亂,給未經聲明的變數賦值在嚴格模式下會導致拋出ReferenceError錯誤
在函數體內,局部變數的優先順序高於同名的全局變數,如果在函數內聲明的一個局部變數或者函數參數中帶有的變數和全局變數重名,那麼全局變數就被局部變數遮蓋
var scope = 'global'; function checkscope(){ var scope = 'local'; return scope; }; checkscope();//'local'
聲明提升(hoisting)
塊級作用域
塊級作用域是指花括弧內的每一段代碼都具有各自的作用域,而javascript沒有塊級作用域。javascript只有函數作用域:變數在聲明它們的函數體以及這個函數體嵌套的任意函數體內都是有定義的
這意味著,變數在聲明之前甚至已經可用。javascript這個特性被非正式地稱為聲明提升(hoisting),javascript函數里聲明的所有變數(不涉及賦值)都被提前到函數體的頂部
[註意]其實除了變數提升,函數也被提升,到函數部分會有詳細介紹
var scope = 'global'; function f(){ console.log(scope);//undefined var scope = 'local'; console.log(scope);//'local' }
//變數聲明提升之後,相當於下麵代碼 var scope = 'global'; function f(){ var scope; console.log(scope);//undefined scope = 'local'; console.log(scope);//'local' }
javascript中沒有塊級作用域,所以一些程式員特意將變數聲明放在函數體頂部,這種源代碼非常清晰地反映了真實的變數作用域
屬性變數
當聲明一個javascript全局變數時,實際上是定義了全局對象window的一個屬性
當使用var聲明一個變數時,創建的這個變數是不可配置的,也就是說這個變數無法通過delete運算符刪除
var truevar = 1; console.log(truevar,window.truevar);//1 1 delete truevar;//false console.log(truevar,window.truevar);//1 1
如果沒有使用嚴格模式並給一個未聲明的變數賦值的話,javascript會自動創建一個全局變數,以這種方式創建的變數是全局對象的正常的可配置屬性,並可以刪除它們
window.fakevar1 = 10; console.log(fakevar1,window.fakevar1);//10 10 this.fakevar2 = 20; console.log(fakevar2,window.fakevar2); //20 20 fakevar = 30; console.log(fakevar,window.fakevar); //30 30 delete window.fakevar1;//true delete this.fakevar2;//true delete fakevar;//true console.log(fakevar1,window.fakevar1);//報錯 console.log(fakevar2,window.fakevar2); //報錯 console.log(fakevar,window.fakevar); //報錯
javascript全局變數是全局對象的屬性,這是在ECMAScript中強制 規定的。局部變數當做跟函數調用相關的某個對象的屬性。ECMAScript3稱為調用對象(call object),ECMAScript5稱為聲明上下文對象(declarative environment record)。javascript允許使用this關鍵字來引用全局對象,卻沒有辦法可以引用局部變數中存放的對象。這種存放局部變數對象的特有性質,是一種對我們不可見的內部實現
參考資料
【1】ES5/語法 https://www.w3.org/html/ig/zh/wiki/ES5/lexical
【2】阮一峰Javascript標準參考教程——語法概述 http://javascript.ruanyifeng.com/grammar/basic.html
【3】W3School-Javascript高級教程——ECMAScript變數 http://www.w3school.com.cn/js/pro_js_variables.asp
【4】《javascript權威指南(第6版)》第3章 類型、值和變數
【5】《javascript高級程式設計(第3版)》第3章 基本概念 第4章 變數、作用域和記憶體問題
【6】《javascript語言精粹(修訂版)》第2章 語法
【7】《javascript DOM編程藝術(第2版)》第2章 Javascript語法