javascript基礎語法——變數和識別符號

小火柴的藍色理想發表於2016-06-01

前面的話

  關於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預定義了很多全域性變數和函式,應該避免把它們的名字用做識別符號名

arguments Array Boolean Date decodeURI decodeURIComponent encodeURI
encodeURIComponent Error eval EvalError Function Infinity isFinite
isNaN JSON Math NaN Number Object parseFloat parseInt RangeError
ReferenceError RegExp String SyntaxError TypeError undefined URIError

  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 

  上面這種命名方法,叫匈牙利命名法。現在當前主流的程式設計規範都不推薦這種命名法

  一般來說,變數的命名要使用名詞,而函式應該是動詞+名稱的形式

var count = 10;
var myName="xiaohuochai";
var found = true;
function getName(){
  return 123;  
}

  對於變數命名來說,儘量要在變數名中體現出值的資料型別

  比如,命名count、length和size表明資料型別是數字,而命名name、title和message表明資料型別是字串。用單個字元命名的變數諸如i、j、k通常在迴圈中使用

  而對於函式和方法命名來說,第一個單詞應該是動詞,下面是一些使用動詞常見的約定

can    函式返回一個布林值
has    函式返回一個布林值
is    函式返回一個布林值
get    函式返回一個非布林值
set    函式用來儲存一個值

 

變數宣告

宣告

  在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)是程式原始碼中定義這個變數的區域

  作用域分為全域性作用域和函式作用域(又叫區域性作用域)兩種

  全域性作用域是最外圍的一個執行環境,在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會自動建立一個全域性變數,以這種方式建立的變數是全域性物件的正常的可配置屬性,並可以刪除它們

  [注意]IE8-瀏覽器下,如果刪除window屬性時,不論該屬性是如何建立的,都會報錯

window.fakevar1 = 10;
this.fakevar2 = 20;
var fakevar3 = 30;
fakevar4 = 40;

console.log(delete fakevar1);//IE8-瀏覽器報錯,其他瀏覽器返回true
console.log(delete fakevar2);//IE8-瀏覽器報錯,其他瀏覽器返回true
console.log(delete fakevar3);//所有瀏覽器都返回false
console.log(delete fakevar4);//所有瀏覽器都返回true

  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語法

 

相關文章