第2章 語法
本章介紹JavaScript的精華部分的語法,并簡要地概述其語言結(jié)構(gòu)。
2.1 空白
空白可能表現(xiàn)為格式化字符或注釋的形式??瞻淄ǔ]有意義,但是偶爾須要用它來分隔字符序列,否則它們就會被合并成一個(gè)單一的符號。例如,對如下代碼來說:
var that = this;
var和that之間的空格是不能被移除的,但是其他的空格都可以被移除。
JavaScript提供兩種注釋形式,一種是用/* */包圍的塊注釋,另一種是以//為開頭的行注釋。注釋應(yīng)該被充分地用來提高程序的可讀性。必須注意的是,注釋一定要精確地描述代碼。沒有用的注釋比沒有注釋更糟糕。
用/* */包圍的塊注釋形式來自于一門叫PL/I(默然說話:Programming Language One的簡寫。當(dāng)中的“I”其實(shí)是羅馬數(shù)字的“一”,它是一種IBM公司在19世紀(jì)50年代發(fā)明的第三代高級編程語言)的語言。在JavaScript中,*/可能出現(xiàn)在正則表達(dá)式字面上,所以塊注釋對于被注釋的代碼塊來說是不安全的。例如:
/*
var rm_a = /a*/.match(s);
*/
導(dǎo)致了一個(gè)語法錯(cuò)誤。所以,我建議避免使用/* */注釋,而用//注釋代替它。
2.2 標(biāo)識符
標(biāo)識符由一個(gè)字母開頭,其后可選擇性地加上一個(gè)或多個(gè)字母數(shù)字或下劃線。標(biāo)識符不能使用下面這些保留字:
abstract
boolean break byte
case catch char class const continue
debugger default delete do double
else enum export extends
false final finally float for function
goto
if implements import in instanceof int interface
long
native new null
package private protected public
return
short static super switch synchronized
this throw throws transient true try typeof
var volatile void
while with
在這個(gè)列表中的大部分保留字尚未用在這門語言中。這個(gè)列表不包括一些本應(yīng)該被保留而沒有保留的字,諸如undefined、NaN和Infinity。JavaScript不允許使用保留字來命名變量或參數(shù)。更糟糕的是,JavaScript不允許在對象字面量中,或者在一個(gè)屬性存取表達(dá)式的點(diǎn)號之后,使用保留字作為對象的屬性名。
標(biāo)識符被用于語句、變量、參數(shù)、屬性名、運(yùn)算符和標(biāo)記。
2.3 數(shù)字
JavaScript只有一個(gè)單一的數(shù)字類型。它在內(nèi)部被表示為64位的浮點(diǎn)數(shù),和Java的double一樣。在JavaScript中,1和1.0是相同的值。
如果一個(gè)數(shù)字字面量有指數(shù)部分,那么這個(gè)字面量的值是由e之前的部分乘以10的e之后部分的次方計(jì)算出來的。所以100和1e2是相同的數(shù)字。
負(fù)數(shù)可以用前綴運(yùn)算符-來構(gòu)成。
值NaN是一個(gè)數(shù)值,它表示一個(gè)不能產(chǎn)生正常結(jié)果的運(yùn)算結(jié)果。NaN不等于任何值,包括它自己。你可以用函數(shù)isNaN(number)檢測NaN。
值Infinity表示所有大于1.79769313486231570e+308的值。
數(shù)字擁有方法(參見第8章)。JavaScript有一個(gè)對象Math,它包含一套作用于數(shù)字的方法。例如,可以用Math.floor(number)方法將一個(gè)數(shù)字轉(zhuǎn)換成一個(gè)整數(shù)。
2.4 字符串
字符串字面量可以被包圍在單引號或雙引號中,它可能包含0個(gè)或多個(gè)字符。\是轉(zhuǎn)義字符。JavaScript在被創(chuàng)建的時(shí)候,Unicode是一個(gè)16位的字符集,所以JavaScript中的所有字符都是16位的。
JavaScript沒有字符類型。要表示一個(gè)字符,只須創(chuàng)建僅包含一個(gè)字符的字符串即可。
轉(zhuǎn)義字符允許把那些正常情況下不被允許的字符插入到字符串中,比如反斜線、引號和控制字符。\u約定允許指定用數(shù)字表示的字符碼位。
“A”===”\u0041”
字符串有一個(gè)ength屬性。例如,”seven”.length是5。
字符串是不可變的。一旦字符串被創(chuàng)建,就永遠(yuǎn)無法改變它。但通過+運(yùn)算符去連接其他的字符串從而得到一個(gè)新字符串是很容易的。兩個(gè)包含著完全相同的字符且字符順序也相同的字符串被認(rèn)為是相同的字符串。所以:
‘c’+’a’+’t’ === ‘cat’
是true。
字符串有一些方法(參見第8章)。
2.5 語句
一個(gè)編譯單元包含一組可執(zhí)行的語句。在web瀏覽器中,每個(gè)<script>標(biāo)簽都提供一個(gè)被編譯且立即執(zhí)行的編譯單元。因?yàn)槿鄙冁溄悠鳎?/span>JavaScript把它們一起拋入一個(gè)公共的全局命名空間中。附錄A有更多關(guān)于全局變量的內(nèi)容。
當(dāng)var語句被用在函數(shù)的內(nèi)部時(shí),它定義了這個(gè)函數(shù)的私有變量。
switch、while、for和do語句允許有一個(gè)可選的前置標(biāo)簽(label),它配合break語句來使用。
語句往往按照從上到下的順序被執(zhí)行。JavaScript可以通過條件語句(if和switch)、循環(huán)語句(while、for和do)、強(qiáng)制跳轉(zhuǎn)語句(break、return和throw)和函數(shù)調(diào)用來改變這個(gè)執(zhí)行序列。
代碼塊是包在一對花括號中的一組語句。不像許多其他的語言,JavaScript中的代碼塊不會創(chuàng)建一個(gè)新的作用域,因此變量應(yīng)該被定義在函數(shù)的頂端,而不是在代碼塊中。
if語句根據(jù)表達(dá)式的值改變程序的控制流程。如果表達(dá)式的值為真,那么執(zhí)行then代碼塊,否則,執(zhí)行可選的else分支。
下面列出的值被當(dāng)作假:
fase
null
undefined
數(shù)字0
數(shù)字NaN
其他所有的值都被當(dāng)作真,包括true,字符串”false”,以及所有的對象。
switch語句執(zhí)行一個(gè)多路分支。它把其表達(dá)式的值和所有指定的case條件進(jìn)行匹配。其表達(dá)式可能產(chǎn)生一個(gè)數(shù)字或字符串。當(dāng)找到一個(gè)精確的匹配時(shí),執(zhí)行匹配的case從句中的語句。如果沒有找到任何匹配,則執(zhí)行可選的default語句。
一個(gè)case從句包含一個(gè)或多個(gè)case表達(dá)式。case表達(dá)式不一定必須是常量。為了防止繼續(xù)執(zhí)行下一個(gè)case,case語句后應(yīng)該跟隨一上強(qiáng)制跳轉(zhuǎn)語句。你可以用break語句去退出一個(gè)switch語句。
while語句執(zhí)行一個(gè)簡單的循環(huán)。如果表達(dá)式值為假,那么循環(huán)將終止。而當(dāng)表達(dá)式值為真時(shí),代碼塊將被執(zhí)行。
for語句是一個(gè)結(jié)構(gòu)更復(fù)雜的循環(huán)語句。它有兩種形式。
常見的形式由三個(gè)可選從句控制:初始化從句(initialization)、條件從句(condition)和增量從句(increment)。首先,;初始化從句被執(zhí)行,它的作用通常是初始化循環(huán)變量。接著計(jì)算條件從句的值。典型的情況是它根據(jù)一個(gè)完成條件檢測循環(huán)變量。如果條件從句被省略掉,則假定返回的條件是真。如果條件從句的值為假,那么循環(huán)將終止。否則,執(zhí)行代碼塊,然后執(zhí)行增量從句,接著循環(huán)會重復(fù)執(zhí)行條件從句。
另一種形式(被稱為for in語句)會枚舉一個(gè)對象的所有屬性名(或鍵名)。在每次循環(huán)中,對象的另一個(gè)屬性名字符串被賦值給for和in之間的變量。
通常你須通過檢測object.hasOwnProperty(variable)來確定這個(gè)屬性名就是該對象的成員,還是從其原型鏈里找到的。
for(myvar in obj){
if(obj.hasOwnProperty(myvar)){
…
}
}
do語句就像while語句,唯一的區(qū)別是它在代碼塊執(zhí)行之后而不是之前檢測表達(dá)式的值。這就意味著代碼塊將總是要執(zhí)行至少一次。
try語句執(zhí)行一個(gè)代碼塊,并捕獲該代碼塊拋出的任何異常。catch從句定義了一個(gè)新的變量,它將接收該異常對象。
throw語句拋出一個(gè)異常。如果throw語句在一個(gè)try代碼塊中,那么控制權(quán)會跳到catch從句中。如果throw語句在函數(shù)中,則該函數(shù)調(diào)用被放棄,且控制權(quán)會跳到調(diào)用該函數(shù)的try語句的catch從句中。
throw語句中的表達(dá)式通常是一個(gè)對象字面量,它包含一個(gè)name屬性和一個(gè)message屬性。異常捕獲器可以使用這些信息去決定該做什么。
return語句會使一人函數(shù)提前返回。它也可以指定要被返回的值。如果沒有指定返回表達(dá)式,那么其返回值是undefined。
JavaScript不允許在return關(guān)鍵字和表達(dá)式之間換行。
break語句會使程序退出一個(gè)循環(huán)語句或switch語句。它可以指定一個(gè)可選的標(biāo)簽,那將會使程序退出帶該標(biāo)簽的語句。
JavaScript不允許在break關(guān)鍵字和標(biāo)簽之間換行。
一個(gè)expression語句可以給一個(gè)或多個(gè)變量或成員賦值,或者調(diào)用一個(gè)方法,或者從對象中刪除一個(gè)屬性。運(yùn)算符=被用于賦值。不要把它和恒等運(yùn)算符===混淆。運(yùn)算符+=可以用于加法運(yùn)算或連接字符串。
2.6 表達(dá)式
三元運(yùn)算符?有三個(gè)運(yùn)算數(shù)。如果第一個(gè)運(yùn)算數(shù)值為真,它產(chǎn)生第二個(gè)運(yùn)算數(shù)的值。但是,如果第一個(gè)運(yùn)算數(shù)為假,它會產(chǎn)生第三個(gè)運(yùn)算數(shù)的值。
表2-1:運(yùn)算符優(yōu)先級
.[]() |
屬性存取及函數(shù)調(diào)用 |
delete new typeof +-! |
一元運(yùn)算符 |
*/% |
乘法、除法、取模 |
+- |
加法/連接、減法 |
>= <= > < |
不等式運(yùn)算符 |
=== !== |
等式運(yùn)算符 |
&& |
邏輯與 |
|| |
邏輯或 |
?: |
三元 |
typeo運(yùn)算符產(chǎn)生的值有’number’、’string’、’boolean’、’undefined’、’function’、’object’。如果運(yùn)算數(shù)是一個(gè)數(shù)組或null,那么結(jié)果是’object’,這是不對的。第6章和附錄A將會有更多關(guān)于typeof的內(nèi)容。
/運(yùn)算符可能會產(chǎn)生一個(gè)非整數(shù)結(jié)果,即使兩個(gè)運(yùn)算數(shù)都是整數(shù)。
函數(shù)調(diào)用引發(fā)函數(shù)的執(zhí)行。函數(shù)調(diào)用運(yùn)算符是跟隨在函數(shù)名后面的一對圓括號。圓括號中可能包含將會傳遞給這個(gè)函數(shù)的參數(shù)。第4章將會有更多關(guān)于函數(shù)的內(nèi)容。
一個(gè)屬性存取表達(dá)式用于指定一個(gè)對象或數(shù)組的屬性或元素。下一章我將詳細(xì)描述它。
2.7 字面量
對象字面量是一種方便指定新對象的表示法。屬性名可以是標(biāo)識符或字符串。這些名字被當(dāng)作字面量名而不是變量名來對待,所以對象的屬性名在編譯時(shí)才能知道。屬性的值就是表達(dá)式。下一章將會有更多關(guān)于對象字面量的信息。
數(shù)組字面量是一個(gè)方便指定新數(shù)組的表示法。第6章將會有更多關(guān)于數(shù)組字面量的內(nèi)容。
第7章將會有更多關(guān)于正則表達(dá)式的內(nèi)容。
函數(shù)字面量定義了函數(shù)值。它可以有一個(gè)可選的名字,用于遞歸地調(diào)用自己。它可以指定一個(gè)參數(shù)列表,這些參數(shù)將作為變量由調(diào)用時(shí)傳遞的實(shí)際參數(shù)(arguments)初始化。函數(shù)的主體包括變量定義和語句。第4章將會有更多關(guān)于函數(shù)的內(nèi)容。
如對本文有疑問,請?zhí)峤坏浇涣髡搲瑥V大熱心網(wǎng)友會為你解答??! 點(diǎn)擊進(jìn)入論壇