- 21天學通JavaScript
- 顧寧燕等編著
- 16038字
- 2018-12-29 13:30:27
第4章 表達式與運算符
上一章講解了變量和常量,本章將講解JavaScript中另一個重要的基礎內容,表達式與運算符。和其他程序語言一樣,JavaScript也有自己的表達式與運算符,而且與C/C++系列語言十分相像。程序設計不外乎就是對問題進行求解,求解的過程需要進行各種各樣的計算。表達式是為計算結果服務的,由操作數和運算符組成。在自然數集中,可以進行的運算有加減乘除等。對應的運算符即是“+、-、×、÷”,接下的內容將對JavaScript中的表達式與運算符一一講解介紹。
● 理解并掌握JavaScript表達式的特點,達到靈活運用要求
● 理解并掌握各個運算符的作用和使用方法
● 結合前兩章,加強練習以熟悉程序語句的編寫
以上幾點是對讀者在學習本章內容時所提出的基本要求,也是本章希望能夠達到的目的。讀者在學習本章內容時可以將其作為學習的參照。
4.1 什么是表達式
表達式是產生一個結果值的式子,JavaScript中的表達式由常量、變量和運算符等組成。表達式可以作為參數傳遞給函數,或者將表達式結果賦予變量保存起來。表達式的結果值有多種類型,比如布爾型、字符串型或數值型等,因此常有邏輯表達式、數值表達式和布爾表達式之說。下面舉例說明如何定義和使用表達式。
【范例4-1】編寫程序,演示表達式的定義和使用。假設初始賬戶余額為1000,經過第一次支付后檢測當前余額能否可以再進行第二次支付,不能則發出提示信息。如示例代碼4-1所示。
示例代碼4-1
01 <script language="javascript"> 02 <!-- 03 var balance = 1000.0; // 余額 04 var willPay = 300.0; // 應支付數額:300 05 balance -= willPay; // 當前余額 06 document.write("當前余額為:" + balance ); // 輸出余額 07 var willPay2 = 800; // 再次支付數額:800 08 if( balance < willPay2 ) // 當余額不足時 09 { 10 document.write( (",不足以進行下次支付!").fontcolor("red") ); // 輸出提示信息 11 } 12 --> 13 </script>
【運行結果】打開網頁文件運行程序,其結果如圖4-1所示。
【代碼解析】該代碼段定義了幾個簡單的表達式。第5行使用變量balance和willPay組成算術表達式,返回當前余額。第8行的if條件語句是邏輯表達式,當balance小于willPay2時返回true值。字符串表達式返回一個字符串,布爾表達式(即邏輯表達式)返回一個布爾值,數值表達式返回一個數值。表達式可以嵌套使用,代碼如下所示。
if ( ( ( b + c ) * 30 + 70 * ( d-3 ) ) * e + 50 > 0 ) // 如果表達式的值大于0 { document.write( "b+c=" + (b+c) ); // 輸出表達式的值 }

圖4-1 余額不足
提示:表達式的使用方式靈活多樣,沒有一定的書寫規則,只需要簡單易讀懂,代碼運行效率高即可。
4.2 什么是操作數
上一節講到表達式時,讀者已經知道其中存在一個重要的組成部分就是操作數。操作數是指表達式中的變量或常量,本書中的操作數也包含表達式的返回值(實際上就是一個常量),常提供計算用的數據。下面是操作數在表達式中的形態。
( A + B + C ) / D
其中,A、B、C、D就是操作數,而“+”和“/”則是操作符,操作符將在下一節介紹。操作數的數據類型受表達式的類型和運算符所支持的數據類型決定,上述代碼中若表達式是數值表達式,則需要A、B、C和D的類型皆為數值或可以轉換為數值。下面舉例說明以加深理解。
【范例4-2】練習操作數的使用,變量和常量皆可作為操作數,如示例代碼4-2所示。
示例代碼4-2
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var A = 1; // 幾個簡單的數值型變量,用于測試 04 var B = 2; 05 var C = 3; 06 var D = 4; 07 var E = ( A + B ) * C + D; // 數學表達式,其中A、B、C和D為操作數 08 document.write( E + 4 ); // 表達式 E+4 中的E和4皆稱為操作數 09 --> 10 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-2所示。

圖4-2 表達式運算結果
【代碼解析】本示例第3~6行定義數個變量作為其后表達的操作數,第8行表達式“E+4”中的4為常量,常量也可以作為操作數。
4.3 運算符概述
前面兩節講過表達式和表達式中的操作數,本節將講解表達式的第三個重要組成部分,即運算符。運算符是指程序設計語言中有運算意義的符號,類似于普通數學里的運算符。通常,每一門數學都定義了一個數集和在數集上可以進行的運算。程序設計語言也一樣,規定了其支持的數據類型及數據可以進行的運算。JavaScript的運算符包含算術運算符、邏輯運算符和一些特殊的運算符,本節將逐一介紹。
4.3.1 什么是運算符
在表達式中起運算作用的符號稱運算符。在數學里,運算符就是指加減乘除等符號。在Java Script中有單目和多目之分,單目運算符帶一個操作數,多目運算符帶多個操作數,代碼如下所示。
( 1 + 2 ) × 3 // 數學表達式 ++A // 左結合遞增
第一行中的運算符是雙目運算符,第二行是單目運算符。其中,“+”也可以作正號,“-”也可以作為負號使用。在不同的場合運算符有不同的含義,依上下文情景而定。舉個例子,在JavaScript中“+”運算符連接兩個數值類型操作數時就作數學加運算。當其連接的兩個操作數是字符串型時將作為“連接”運算,即將兩個串接成一個串。JavaScript的運算符極其豐富,接下來的內容將對其進行更深入的講解。
4.3.2 操作數的分類
表達式中的操作數要么是常量要么是變量,常量和變量都有其特定的數據類型。構成表達式的操作數的數據類型依變量或常量的類型來確定,見下面的示例。
【范例4-3】操作數的類型,如示例代碼4-3所示。
示例代碼4-3
01 <script language="javascript">// 腳本程序開始 02 <!-- 03 var a = "4"; // 字符串變量 04 var b = 4; // 數值型變量 05 var c = a + b; // 下面表達式中,操作數 b先被轉換為字符串類型, 06 alert( c ); // 即“b”再與字符串類型操作 a 進行 “+” 運算 07 --> 08 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-3所示。
【代碼解析】該代碼段第3、4行定義兩個變量,a為字符串型,b為數值型。目的是將兩者進行“+”運算,以測試其結果。第5行操作數b的類型由數值型轉換為字符串型。

圖4-3 數字與字符連接
提示:JavaScript操作數的類型是靈活多變的,通常由運算符類型、目標場合需求的類型來定,讀者編程時要多加測試。
4.4 算術運算符簡介
算術運算符是定義數學運算的符號,有數學意義的運算稱為算術運算。通常在數學表達式中使用,實現數值類型操作數間的數學計算。JavaScript中要包括加法、減法、乘法、除法、取模、正負號、遞增和遞減等。
4.4.1 加法運算符
加法運算符使用數學符號“+”,屬于雙目運算符,返回兩個操作數的算術和。操作數的類型要求為數值型,如果是字符串型則意義不同,主要運用在數值求和的場合,其語法如下所示。
操作數1 + 操作數2
【范例4-4】編寫程序,演示加法運算符,求某公司的總人數,如示例代碼4-4所示。
示例代碼4-4
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var departmentA = 1000; // 部門A 1000人 04 var departmentB = 375; // 部分B 375人 05 var total = departmentA + departmentB; // 公司總人數 06 document.write( "公司總人數:" + total ); // 輸出人數信息 07 --> 08 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-4所示。

圖4-4 總人數
【代碼解析】第3、4行分別給出公司兩個部門各自的人數。第5行通過使用“+”運算符進行人數求和。
提示:注意加法運算符與字串型操作數結合的情況,操作數類型為字符串型時其意義為連接運算。
4.4.2 減法運算符
減法運算符使用數學符號“-”,屬于雙目運算符,返回兩個操作數的算術差,操作數類型要求為數值型。含義與數學上的減法計算完全一樣,使用的形式如下所示。
操作數1 - 操作數2
【范例4-5】編寫程序,演示減法運算符的功能。某小汽車平均耗油量為7.5升每100公里,求其100公里行程后的剩余油量。如示例代碼4-5所示。
示例代碼4-5
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var totalGas = "20升"; // 汽油總量 04 var used = "7.5升"; // 開出100公里后消耗 05 var overplus = parseFloat( totalGas ) - parseFloat( used ); // 剩余 06 document.write( "車子已經開了100公里,還剩汽油" + overplus + "升" ); // 100公里時輸出提示 07 --> 08 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-5所示。

圖4-5 剩余油量
【代碼解析】該代碼段第3、4行給出汽油總量和當前消耗量。第5行使用前面講過的parseFloat方法將字符串解析為數字,并求出汽油剩余量。
注意:JavaScript中數學運算符運用于非數字型操作數時,將發生隱式類型轉換。
4.4.3 乘法運算符
乘法運算符使用符號“*”,屬于雙目運算符,返回兩個操作數的算術積。操作數類型要求為數值型。運算意義上完全等同于數學上的乘法計算,使用語法如下所示。
操作數1 * 操作數2
【范例4-6】乘法運算符的算術意義。某公司給其屬下300名員工發獎金,每人370元,求獎金預算總額。如示例代碼4-6所示。
示例代碼4-6
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var employee = 300; // 雇員總數 04 var prize = 370; // 每人獎金數額 05 var total = employee * prize; // 預算總額 06 alert( "預算:" + total + "元" ); // 輸出總額 07 --> 08 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-6所示。
【代碼解析】該代碼段第5行返回變量employee和prize的積,即預算總額。“*”完全就是數學意義上的乘法符號。

圖4-6 總預算
4.4.4 除法運算符
除法運算符使用符號“/”,也屬于雙目運算符,操作數類型要求為數值型。其返回兩個操作數之商,JavaScript返回的商是實數集內的數據,也就是浮點型數據。意義上等同于數學中的除法運算,因此可用在求商的場合,使用語法如下:
操作數1 / 操作數2
操作數1、操作數2都是數值類型,操作數2不能為0,否則將產生不正確的結果。除數為零的情況在其他編程語言中將發生一個異常,而JavaScript僅返回一個非數字(NaN)結果。
【范例4-7】除法運算符的數學含義。三個賊平均瓜分盜來的1000元錢,輸出每個人所得的數額,如示例代碼4-7所示。
示例代碼4-7
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var total = 1000; // 1000元 04 var thieves = 3; // 三個賊 05 alert( "每人瓜分所得:" + total/thieves + "元" ); // 輸出三人瓜分后所得數額 06 --> 07 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-7所示。
【代碼解析】該代碼段說明了除法運算符的數學意義,在第5行返回total除以thieves的商。

圖4-7 計算結果
4.4.5 取模運算符
取模運算符使用符號“%”,其作用是求一個數除以另一個數的余數。操作數的類型要求為數值型或能轉換為數值型的類型,屬于雙目運算符。事實上“模”可以這樣理解,如手表上的小時刻度,每到12點以后就是1點,此鐘表的模為12。通常取模運算可以求取某個數的倍數,如下面示例所示。
【范例4-8】求1~1000中3的倍數,如示例代碼4-8所示。
示例代碼4-8
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 for( i = 1; i<1000; i++ ) // 找出0到1000中3的公倍數 04 { 05 if( i%3 == 0 ) // 當模3為0時即是3位數 06 { 07 document.write( i + " " ); // 輸出 08 } 09 } 10 --> 11 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-8所示。

圖4-8 1~1000中3的倍數
【代碼解析】該代碼段第3行使用for循環從1到1000中取得999個數。第5行將取得的數模3,如果為0則當前數是3的倍數。
4.4.6 負號運算符
負號運算符使用符號“-”,取負也就是等于取反。等同于數學意義上的負號,屬于單目運算符,語法如下:
-操作數
【范例4-9】使用取反運算符求某個數的負值,如示例代碼4-9所示。
示例代碼4-9
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var a = -1; // 負數 04 var b = -a; // 取反 05 alert( a + "取反后得:" + b ); // 輸出 06 --> 07 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-9所示。

圖4-9 -1取反為1
【代碼解析】該代碼段將一個變量a的值取反后存入變量b中,再將變量b輸出,兩次取反等于原來的數。
4.4.7 正號運算符
正號運算符使用符號“+”,針對數值類型操作數,意義上等同于數學上的正號。屬于單目運算符,語法如下:
+ 操作數
【范例4-10】學習正號運算符的特點,如示例代碼4-10所示。
示例代碼4-10
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var a = -1; // 定義變量并賦予負值 04 var b = +a; // 定義變量并賦予正值 05 var c = +5; // 定義變量并賦予正值 06 alert( "a、b和c的值分別為:" + a + "、" + b + "和" + c ); // 輸出各變量的值 07 --> 08 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-10所示。
【代碼解析】該代碼段第4、5行對變量b、c使用“+”(正號運算符),通過第6行的輸出來看,正號運算符沒有任何意義。

圖4-10 輸出變量的值
4.4.8 遞增運算符
遞增運算符使用符號“++”,也稱為自增運算符,屬于單目運算符。可使數值類型的變量值自增一,操作數只能是變量。使用形式分左結合與右結合兩種,左結合在表達式中的效果是先遞增再使用,右結果則是先使用再遞增。語法如下:
變量名++; // 右結束遞增 ++變量名; // 左結合遞增
【范例4-11】使用遞增運算符對一個數進行遞增操作,理解遞增運算符的特點。如示例代碼4-11所示。
示例代碼4-11
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var a = 10; // 數值型變量 04 document.write( "<li>a的初始值為:" + a ); // 輸出初始值 05 if( ++a == 11 ) // ++左結合,此時if測試條件成立 06 { 07 document.write( "<li>左結合,先遞增再使用。" ); // 輸出提示信息 08 } 09 if( a++ == 12 ) // ++右結合,此時if測試條件不成立 10 { 11 document.write( "<li>右結合,先遞增再使用。" ); // 輸出提示信息 12 } 13 else 14 { 15 document.write( "<li>右結合,先使用再遞增。" ); // 輸出提示信息 16 } 17 --> 18 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-11所示。

圖4-11 左右結合對比
【代碼解析】該代碼段第5行作用于變量a的遞增運算符與a結合形式為左結合,其先進行遞增運算后再與11進行比較。第9行a與遞增運算符結合形式為右結合,則先a先與12比較后返回一個布爾值作為if的測試條件,再進行遞增操作,因此if條件為假。
提示:請區別左結合與右結合所進行的操作分別是什么,這樣的疏漏很難發現。
4.4.9 遞減運算符
遞減運算符使用符號“--”,也稱為自減運算符,可使變量的值自減一。效果與遞增運算符完全相反,也有左結合與右結合之分,情況與遞增運算符相同,在此不再贅述,使用形式如下:
變量名--; // 右結合遞減 --變量名; // 左結合遞減
【范例4-12】使用遞減運算符對一個數進行遞減操作,掌握自減運算符的特點。如示例代碼4-12所示。
示例代碼4-12
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var a = 5; // 定義一個數字變量 04 document.write( a ); // 輸出a原來的值 05 document.write( "<br>" ); // 輸出換行標簽 06 a-- ; // a自減一(右結合) 07 document.write( a ); // 輸出變量a 08 document.write( "<br>" ); // 輸出換行 09 --a; // a自減一(左結合) 10 document.write( a ); // 輸出變量a 11 document.write( "<br>" ); // 輸出換行 12 if( --a == 2 ) // 測試左、右結合位于表達式中的情況 13 { 14 document.write( "<li>左結合的情形" ); // 輸出提示信息 15 } 16 if( a-- == 2 ) // 等于2時 17 { 18 document.write( "<li>右結合的情形" ); // 輸出提示信息 19 } 20 --> 21 </script> // 腳本程序結束
【運行結果】打開網頁文件運行程序,其結果如圖4-12所示。

圖4-12 左右結合對比
【代碼解析】該代碼段第3~10行定義一個變量并輸出其進行遞減操作后的值。第12行使用左結合的方式參與構成條件表達式,從輸出結果表明左結合是先執行遞減操作后再使用變量的值參與表達式的計算,而右結合運算順序相反。
警告:遞增遞減運算符的操作數只能是變量。
4.5 關系運算符簡介
關系運算符比較兩個操作數大、小于或相等的運算符。返回一個布爾值,表示給定關系是否成立,操作數的類型可以任意。包括相等、等同、不等、不等同、小于、小于或等于、不小于、大于、大于或等于這幾種。
4.5.1 相等運算符
相等運算符使用符號“==”,判斷兩個操作數是否相等。如果相等返回布爾值true,否則返回false。屬于雙目運算符,兩個操作數的數據類型可以任意。通常與條件測試語句結合使用, JavaScript是弱類型語言,因此可以比較兩種不同類型的數據。運行時,“==”操作符將兩端的操作數轉換為同一種數據類型后再作比較。使用語法如下:
操作數A == 操作數B
【范例4-13】JavaScript中用“==”判斷兩者是否相等,理解掌握相等運算符的特點。如示例代碼4-13所示。
示例代碼4-13
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var a = "10"; // 字符串變量 04 var b = 10; // 數值型變量 05 if ( a == b ) //a、b將發生類型轉換 06 { 07 alert( "a等于b,“==”使兩端的操作數發生了類型轉換" ); // 輸出提示信息 08 } 09 --> 10 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-13所示。

圖4-13 非嚴格相等
【代碼解析】該代碼段測試了JavaScript中“==”的功能和特點。第5行判斷a與b的相等性時a和b被轉換為同一種數據類型。
提示:“==”不是嚴格相等性判斷,只要類型轉換后的數據仍然相等的話就返回true。
4.5.2 等同運算符
前面講述的相等運算符“==”進行的是非嚴格意義上的相等性判斷,即通過類型轉為后相等的也返回true。而等同運算符“===”是嚴格意義上的相等,兩個值和它們的類型完全一致時才返回true,使用語法如下:
操作數1 === 操作數2
兩個操作數可以是變量也可以是常量,數據類型可以是任意有效的JavaScript類型,下面舉例區別等同與相等運算符的作用。
【范例4-14】比較“相等運算符”和“等同運算符”的區別,如示例代碼4-14所示。
示例代碼4-14
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var a = "10"; // 字符串變量 04 var b = 10; // 數值型變量 05 if ( a == b ) // a、b將發生類型轉換,轉換為同一種類型 06 { 07 document.write( "<li>在非嚴格意義上,a等于b" ); // 輸出提示信息 08 } 09 if( a === b ) // 等同運算符判斷a、b的相等性 10 { 11 document.write( "<li>a嚴格等于b" ); // 輸出提示信息 12 } 13 else // 都不相等時 14 { 15 document.write( "<li>在嚴格意義上,a不等于b" ); // 提示 16 } 17 --> 18 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-14所示。
【代碼解析】該代碼段對兩個不同類型的變量進行相等性判斷。第5行進行的是非嚴格相等性判斷,條件表達式返回true。第9行進行的是嚴格相等性判斷,因a、b的類型不同,表達式返回false。
4.5.3 不等運算符
不相等運算符使用符號“!=”,屬于雙目運算符,返回一個布爾值表示兩個操作數是否相等。兩個操作數類型任意,同時可以是變量也可以是常量。使用語法如下:
操作數1 != 操作數2

圖4-14 對比嚴格與非嚴格相等
不等運算兩端的操作數如果經過類型轉換后仍不相等的話同樣返回true,否則返回false。不是嚴格意義上的不相等。
【范例4-15】在幾個學生當中找出名為“楊宗楠”的學生,并用紅色字體標記之,如示例代碼4-15所示。
示例代碼4-15
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var students = new Array( "楊宗楠", "楊玉婷", "李莉" ); // 學生名單 04 for( index in students ) // 遍歷名單 05 { 06 if( students[index] != "楊宗楠" ) //不是“楊宗楠”則輸出為黑色字體 07 { 08 document.write( "<li>" + students[index] ) // 普通輸出 09 } 10 else // 否則 11 { 12 document.write("<li><font color=red>"+students[index]"</font>"); // 紅字輸出 13 } 14 } 15 --> 16 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖4-15所示。

圖4-15 標記目標名字
【代碼解析】該代碼段第3行創建一個數組students以記錄學生的名字,共有三個學生。第4~14行遍歷學生表,并輸出各學生名字,對目標名字以紅色字輸出。第6行使用了不等于運算符“!=”判斷兩個名字是否相等。
4.5.4 不等同運算符
不等同運算符使用符號“!==”,屬于雙目運算符。效果與等同運算符正好相反,如果兩個數嚴格不相等則返回true,使用語法如下:
操作數1 !== 操作數2
運算符兩端的操作數可以是變量或常量,變量或常量的數據類型任意。不等同于運算符使用場合并不多,用法如下所示。
01 var phone1 = "13800000000"; // 定義字符串型的電話號碼 02 var phone2 = 13800000000; // 定義數值型電話號 03 if( phone1 !== phone2 ) // 嚴格不相等判斷,此時返回true 04 { 05 alert( "兩個電話號碼不相等" ); // 提示 06 }
前面講過相等、不相等,等同、不等同4個運算符,前兩者是非嚴格意義上的等與不等,后兩者是嚴格意義上的等與不等,讀者要注意這其中的區別。
4.5.5 小于運算符
小于運算符是判斷第一個操作數是否小于第二個操作數的運算符,返回一個布爾值。使用符號“<”表示,常用于邏輯表達式中。使用語法如下:
操作數1 < 操作數2
如果操作數1小于操作數2時則表達式返回true,否則返回false。兩個操作數可以是變量也可以是常量,變量或常量可以是任意有效的JavaScript數據類型。小于運算符應用廣泛,比如可以用于篩選出目標數據,如下面示例所示。
【范例4-16】現有一網絡游戲點卡銷售系統的購買頁面,要求輸入的點卡數量不小于1,需要在用戶確定付賬時檢測其輸入的數據是否符合要求,如示例代碼4-16所示。
示例代碼4-16
01 <body> <!--文檔體開始--> 02 <!--配置一個文件輸入框和一個按鈕,與用戶交互用--> 03 <li>50點點卡單價為4.5元,您確定購買 <!--價格信息--> 04 <input id="Text1" style="width: 31px; height: 18px" type="text" />張。 <!--文本框--> 05 <input id="Button1" type="button" value="確定支付" onclick="return Button1_ onclick()" /> <!--按鈕 --> 06 (最多不能超過5張) 07 <script language="javascript"> // 腳本程序 08 <!-- 09 function Button1_onclick() // 按鈕單擊事件處理程序 10 { 11 if( (Text1.value < 1) || isNaN(Text1.value) ) // 輸入小于0或不是數字,則清除文本框內容并要求重輸 12 { 13 alert( "您的輸入不正確,請重新輸入" ); // 警告 14 Text1.value = ""; // 清空輸入框 15 } 16 else // 輸入合法則統計總金額 17 { 18 alert( "您的應當支付:" + Text1.value * 4.5 + "元" ); // 輸出應該支付的金額 19 } 20 } 21 --> 22 </script> <!--腳本程序結束--> 23 </body> <!--文檔體開始-->
【運行結果】打開網頁文件運行程序,其結果如圖4-16所示。

圖4-16 操作效果
【代碼解析】該代碼段實現一個簡單的賬單驗證功能。第3~6行用一個文本框和一個按鈕實現用戶界面,并在按鈕上綁定按鈕單擊事件處理程序。第9~20行定義一個函數作為按鈕單擊事件處理函數。其中第11行用小于運算符檢測輸入的點卡數量是否少于1張,或者輸入的是非數字,如果這兩條件至少有一個成立則要求重新輸入。第18行在用戶輸入點卡數量正確的情況下輸出統計金額。
注意:使用運算符時請注意操作數的類型。
4.5.6 大于運算符
大于運算符與小于運算符的運算效果正好相反,使用符號“>”,主要用于測試兩個操作數的大小關系。使用語法如下:
操作數1 > 操作數2
操作數可以是變量或常量且數據類型是任意有效的JavaScript類型。當第一個操作數大于第二個操作數時表達式返回true,否則返回false,下面舉例加深讀者理解。
【范例4-17】現有一個購物網站的支付確認頁面,提供結算用戶賬單信息的功能。如果當前余額不足以進行本次支付則取消操作,否則輸出結算信息。如示例代碼4-7所示。
示例代碼4-17
01 <body style="font-size: 12px"> <!--頁面普通字體大小為12px--> 02 <script language="javascript"> 03 <!-- 04 var actTotal = 109.7; // 賬單總額 05 var payTotal = 123.45; // 當前應該付的款額 06 document.write( "<li>您賬上余額:" + actTotal + "元<br>" ); // 輸出賬面信息 07 document.write( "<li>您需要支付:" + payTotal + "元<br>" ); 08 document.write( "<input id=\"BtnPay\" type=\"button\" value=\"確認支付\" onclick=" 09 + "\"return BtnPay_onclick()\" style=\"width: 150px\" /><br>" ); // 生成“確認支付”按鈕 10 if( payTotal > actTotal ) // 如果余額不足,支付按鈕設置為失效 11 { 12 document.write( "信息:<fontcolor=red>您的余額不足,無法完成支付!</font>"); 13 BtnPay.disabled = true; 14 } 15 else // 余額夠用于支付,則啟用按鈕 16 { 17 BtnPay.disabled = false; 18 } 19 function BtnPay_onclick() // 按鈕單擊事件處理函數,主要處理表達發送輸出結算信息 20 { 21 // Todo: // 在此添加發送數據到服務器的操作代碼 22 document.write( "<li><font color=red>已經完成支付</font>" ); 23 document.write( "您賬上余額:" + (actTotal-payTotal) + "元<br>" ); 24 } 25 --> 26 </script> 27 </body>
【運行結果】打開網頁文件運行程序,其結果如圖4-17所示。

圖4-17 支付前檢查余額
【代碼解析】該代碼段實現了支付頁面簡單的功能,主要驗證用戶的余額是否足以進行交易。第1行設置本頁普通字體的尺寸。第4、5行手工設定賬戶余額和該付數額。第8行生成一個按鈕,主要用于確認支付操作。第10~14行對余額進行判斷,如果夠用則啟用“確認支付”按鈕。否則該按鈕變灰,無法使用,使得余額不足時不能進行交易。
4.5.7 小于或等于運算符
小于或等于運算符判斷第一個操作數和第二個操作數間是否是小于等于關系,使用符號“<=”。當第一個操作數小于或等于第二個操作數時表達式返回true,否則返回false。使用語法如下:
操作數1<=操作數2
兩個操作數可以是變量或常量,數據類型可以是任意有效的JavaScript類型。通常用于取大小關系的場合,示例如下:
01 var a = 5; // 數值變量a 02 var b = 5; // 數值變量b 03 if( a <= b ) // 如果a等于小于b則 04 { 05 // todo // 執行語句 06 }
以上條件表達式返回true,因為有a=b。只要a=b或a<b即可返回true。相反的情況是當a>b時返回false。
注意:字符串也可以比較大小。
4.5.8 大于或等于運算符
大于等于運算符與小于等于運算符有部分不同的地方,其判斷第一、第二個操作數間的關系是否是大于等于關系。滿足此關系則表達式返回true否則返回false。操作數的類型要求與小于等于運算符相同,使用“>=”表示。使用語法如下:
操作數1 >= 操作數2
該運算符通常應用于求大小關系的場合。例如當用戶輸入其年齡為1000,這是不太可能的,因此可以將年齡數據視為不符合要求,如下述代碼所示。
01 var age = 1000; // 年齡 02 if( age >= 100 ) // 大于等于100時 03 { 04 age = 0; // 更正為0 05 }
age在此處等于1000,因此條件表達式返回true,執行流程進入if語句塊中。大于等于運算符只需要滿足第一個操作數大于或等于第二個操作數表達式即可返回true。
4.5.9 in運算符
前面介紹過的運算符都與其在數學上的意義相同或相似,但JavaScript畢竟不是數學,因此也有很多獨特的運算符。in運算符就是其中之一,in運算符檢查對象中是否有某特定的屬性。通常,在數組對象中存在一種稱為元素索引的屬性集合,該集合的每個元素都是一個非負整型值。因此可以通過in運算符取得數組索引集合,這是個非常有用的運算符。語法如下:
result = property in Object;
property為Object對象包含的屬性集合,result接收從集合中按順序逐一提取的屬性。in運算符應用十分廣泛,通常用于遍歷集合中的所有元素,比如數組,下面舉例說明以加深印象。
【范例4-18】有5種水果的價格數據,分別是梨3.5元、葡萄7元、香蕉2元、蘋果3元和荔枝6元。現需要將這5種水果的價格顯示在網頁的價目表上以供客戶查詢,如示例代碼4-18所示。
示例代碼4-18
01 <body> 02 <script language="javascript"> // 腳本程序開始 03 <!-- 04 var fruit = new Array( "梨", "3.5", "葡萄", "7", "香蕉", "2", "蘋果", 3, " 荔枝", 6 ); // 水果數組 05 for ( index in fruit ) // 使用in運算符遍歷水果數組 06 { 07 if( index%2 == 0 ) // 如果索引為偶數即為水果名 08 { 09 document.write( "<li>" + fruit[index] + ":"); 10 } 11 else // 元素索引為奇數則為對應水果的價格 12 { 13 document.write( fruit[index] + "元\t" ); // 輸出水果價格 14 document.write( "<input id=\"Button"+ index + "\" type=\"button\" " // 生成購買按鈕 15 +"value=\"購買\""+"onclick=\"return Button1_onclick(this.serial -1)\" serial=\"" 16 + index +"\" /><br>" ); // 輸出 17 } 18 } 19 function Button1_onclick( arg ) // 購買按鈕的單擊事件處理漋數 20 { 21 alert("您即將購買:" + fruit[arg] ); // 根據按鈕序列號判斷客戶購買的水果 22 } 23 --> 24 </script> 25 </body>
【運行結果】打開網頁文件運行程序,其結果如圖4-18所示。

圖4-18 商品列表
【代碼解析】該代碼段實現了水果價格發布功能,每種水果都生成與其對應的一個購買按鈕。第4行使用一個數組來保存水果的名稱和其價格,偶數元素保存水果名,奇數元素保存價格。第7~10行輸出偶數元素,成為一行信息的第一部分。
第11~18行輸出價格(奇數元素)作為對應信息行的第二部分,同時生成一個“購買按鈕”。購買按鈕的單擊事件處理程序綁定到第19~22行定義的函數,處理用戶單擊“購買”按鈕的事件。
提示:本例綜合了前面所學的知識,也用到了后面才講到的知識,讀者現在不必深究,重點在于理解in運算符。
4.5.10 instanceof運算符
instanceof運算符返回一個布爾值,表明某對象是否是某個類的實例。得到一個對象時,有時需要得知其屬于哪個類,確定對象的身份。使用語法如下:
result = Obj instanceof Class
如果Obj是類Class的對象,剛result值為true否則為false。通常使用在布爾表達式中,以確定對象的類型,比如有一個數組對象,可以使用instanceof運算符來確定該對象是否是數組類型。如下面代碼所示。
var nameList = new Array( "Lily", "Bob", "Petter" ); // 創建一個名字數組 var nameJet = "Jet"; // Jet的名字 if( nameList instanceof Array ) // 如果nameList是屬性數組對象的實例,則 { nameList.push(nameJet ); // 將Jet的名字添加到數組中 } if( nameJet instanceof Array ) // 檢查nameJet是否是數組對象的實例 { // 一些有效的程序語句 }
以上代碼段中if語句測試表達的值返回true,因為nameList正是Array類的對象。然而nameJet則不是Array類的對象,因此第二個if語句的測試條件為false。第二對花括號中的語句不會被執行。
提示:使用instanceof可以判斷某一對象是否是某一個類的實例,當要確定某個對象的類型時可以使用typeof運算符。
4.6 字符串運算符簡介
前面講過了常見的數學運算符、關系運算符和一些特殊的運算符,本節將介紹與字符串相關的運算符。字符串也是一種數據,同樣也存在相應的計算,因此程序設計語言也為字符串定義了相應的運算符。主要包括+、>、<、>=和<=這幾種。接下來逐一介紹每個運算符的功能。
運算符“+”,稱為連接運算符,它的作用是將兩個字符串按順序連接成為新的字符串。這大大簡化了字符串表達式的寫法,使用語法如下:
result = string1 + string2; // 連接字符串
string1和string2可以是字符串變量或常量,連接后形成的新串存入變量result中。也可以將連接后的新串作為參數傳遞,代碼如下所示。
var str1 = "今天星期幾了?"; // 字符串變量 var str2 = "星期五"; // 字符串變量 document.write( str1 + str2 ); // 輸出連接后的字符串
上述代碼中將str1和str2用連接運算符連接為一個串后作為參數傳遞給write方法。document對象的write方法要求一個字符串作為參數。
4.7 賦值運算符簡介
賦值運算符“=”,用于給變量賦值。賦值運算符將值與變量綁定起來,也就是說,值寫入了變量所引用的內存單元。通常,僅聲明的變量是沒有初始值的,給變量填入數據最直接的辦法就是使用賦值運算符將值賦予變量。代碼如下所示。
var name = "Jet"; // 字符串
以上代碼將“Jet”賦予變量name,“=”運算符左邊的操作數稱為左值,其右邊的操作數稱為右值。左值必須是變量,右值可以是變量、常量或表達式。讀者要注意區分以下兩個概念。
● 聲明,指僅宣布變量的存在,但沒有為其實際分配存儲空間。代碼如下所示。
var name; // 聲明變量
變量name僅聲明,表示它的存在,系統并不為它分配存儲空間。
● 定義,聲明并賦值。系統真正為變量分配存儲空間,代碼如下所示。
var name = "Lily"; // 定義字符串變量
4.8 邏輯運算符簡介
除了數學運算外,程序設計語言還包含另一種重要的運算,邏輯運算。通常是與、或、非和移位等,JavaScript也為此類運算定義了相應的運算符。包括邏輯與、邏輯或和邏輯非等,本節將逐一講解。
4.8.1 邏輯與運算符
邏輯與運算符“&&”,屬于雙目運算符,操作數被當成布爾類型,可以是變量也可以是常量。“&&”運算符的使用語法如下:
操作數1 && 操作數2 // 與運算
將第一個操作數和第二個操作數相與,返回一個布爾值。在日常生活中,常遇到這樣的情形,達到兩廂情愿需要兩個條件,A喜歡B,B也喜歡A。其中少一個都不行。為了判斷A和B是否達到了兩廂情愿,只需要將A和B這兩條件作相與運算即可。代碼如下所示。
01 var AWish = true; // A同意 02 var BWish = true; // B同意 03 if( AWish && BWish ) // 邏輯表達式 04 { 05 // 達到兩廂情愿 06 }
邏輯與運算符通常用于判斷多個條件同時成立的場合,多個條件相與時需要所有條件都成立表達式才返回true,下面舉例以加深理解。
【范例4-19】現有一付費影片下載網站的某個頁面,其上某個影片對下載用戶有要求:必須是2級注冊用戶,并且下載點數至少30點余額。不滿足條件的用戶不予以下載,限制功能的實現如示例代碼4-19所示。
示例代碼4-19
01 <body> <!--文檔體開始--> 02 <script language="javascript"> // 腳本程序開始 03 <!-- 04 function Button1_onclick() // 按鈕事件處理程序 05 { 06 var isRegistered = true; // 注冊用戶 07 var level = 3; // 級數為3 08 var blance = 25; // 賬戶余額 09 if( isRegistered && ( level >= 2 ) && ( blance >= 30 ) ) // 必須是注冊用戶、等級大于等于2、余額大于30 10 { 11 alert( "您可以下載本資源" ); // 當前用戶條件都滿足時 12 } 13 else 14 { 15 alert( "您不能下載本資源" ); // 至少有一個條件不滿足時 16 } 17 } 18 --> 19 </script> <!--腳本程序結束--> 20 單擊下載本影片 21 <input id="Button1" type="button" value="下載" onclick="return Button1_ onclick()" /> <!--下載按鈕--> 22 </body>
【運行結果】打開網頁文件運行程序,結果如圖4-19所示。

圖4-19 下載前檢測
【代碼解析】該代碼段實現了影片下載前檢測用戶狀態的功能。第21行設置一個下載按鈕,用戶單擊它即可啟動下載。第4~17行定義一個函數作為下載按鈕的單擊事件處理程序,此程序檢測用戶的狀態。第9行用與運算符檢測三個條件,“是否已經注冊”、“是否達到至少2級”和“是否至少有30點的余額”這三個條件,只要至少一個條件不成立,表達式即返回false。從而不能進入下載頁面,條件都成立則可以下載。
提示:邏輯運算符也可以用于非邏輯表達式中。
4.8.2 邏輯或運算符
邏輯或運算符“||”,屬于雙目運算符,對兩個操作數進行或運算并返回一個布爾值。返回值表明兩個操作數中是否至少有一個的值為true,操作數可以是常量或變量,類型皆被轉換為布爾型。使用語法如下:
操作數1 || 操作數2
邏輯或運算符通常用于判斷多個條件中至少有一條成立即可通過測試的場合。例如某個人僅憑身份證或學生證即可領取郵局里的郵包,可使用邏輯或運算符,代碼如下所示。
01 var identity_card = true; // 身份證 02 var student_IDC = false; // 學生證 03 if( identity_card || student_IDC ) // 是否帶兩了至少一種證件 04 { 05 // 允許領取 06 } 07 else // 否則 08 { 09 // 不允許領取 10 }
上述代碼中只需要identity_card或student_IDC為true,if語句的測試條件為真,則允許領取郵包,否則不允許。
4.8.3 邏輯非運算符
邏輯非運算符“!”,屬于單目運算符。對操作數的邏輯值取反,操作數可以是變量或常量。類型可以是任意JavaScript數據類型,和邏輯非運算符結合后的數據類型皆被當做布爾型。如果原來的值為true運算后將為false,反之為true。語法如下:
var v = false; // 布爾型變量
邏輯非運算符通常用于測試當某條件不成立時(即為false),再通過一次取反條件則成立。條件語句測試通過,以原條件不成立為執行前提的代碼就得到執行,代碼如下所示。
01 var isBob = false; 02 if( !isBob ) // 如果不是Bob時 03 { 04 // 如果此用戶不是Bob時而采取的行動 05 }
4.9 位運算符簡介
前面所講的邏輯與、邏輯或和邏輯非都是依據操作數的值轉換為布爾值后參與計算。例如非零值為true,零值為false。而位運算符則對變量的二進制位間進行邏輯運算,因而取得一個新的值。位級運算符包括位與、位或、位異或、位非和移位運算符。
學習位運算符之前,應該先了解存儲單元的位模型。通常計算機中每一個內存單元是一個字節,一個字節由8個二進制位組成,二進制位是計算機里的最小的信息單元,模型如圖4-20所示。

圖4-20 內存單元位模型
圖4-20中黑粗邊框表示一個內存字節單元,由8個二進制位構成。該單元的二進制值為01000110,是無符號數字74。位運算符對變量進行的運算是發生在二進制位級別,因此返回的值通常不用做布爾值。
4.9.1 位與運算符
位與運算使用符號“&”,屬于雙目運算符。兩個操作數的對應二進制位相與,對應兩個位都為1時結果值中對應位也為1,否則為0。結果值的長度和兩個操作數中位數最多者相同,通常用于測試某個操作數中的某位是否為1,作為開關使用。語法如下:
var result = 操作數1 & 操作數2;
【范例4-20】某地下通道有8條行車線,每5分鐘只能隨機允許其中數條通車。用紅綠燈控制車道的停通,1表示綠燈,0表示紅燈。測試1、3、5、7車道是否開通的程序如示例代碼4-20所示。
示例代碼4-20
01 <body> <!--文檔體開始--> 02 <script language="javascript"> // 腳本程序開始 03 <!-- 04 function Button1_onclick() // 按鈕單擊事件處理程序 05 { 06 var currentState = 215; // 目前車道開放的狀態 07 if ( (currentState & 85) == 85 ) // 測試第1、3、5、7位是否為1 08 { 09 alert( "已經開通1、3、5、7車道" ); // 輸出信息 10 } 11 else // 其中至少有一位不為1 12 { 13 alert( "1、3、5、7車道目前處于關閉狀態" ); // 輸出信息 14 } 15 } 16 --> 17 </script> <!--腳本程序結束--> 18 <!-檢查按鈕--> 19 <input id="Button1" type="button" value="查看1、3、5、7道是否已經通車" 20 onclick="return Button1_onclick()" /> 21 </body> <!--文檔體結束-->
【運行結果】打開網頁文件運行程序,結果如圖4-21所示。

圖4-21 程序運行效果
【代碼解析】該代碼段使用位與運算符檢測一個字節單元中的第1、3、5、7位是否為1,將該單元的值與85做位與運算即可實現。第6行定義一個變量表示當前地下車道開放的狀態, 215的二進制碼為11010111。表示第1、2、3、5、7、8道開通。第7行將狀態碼215與85做位與運算,85的二進制碼為01010101,表示第1、3、5、7道開通。位與操作后如果結果為85則表示目標通道開通,否則至少有一條目標通道是關閉的。
4.9.2 位或運算符
位或運算符“|”原理與位與運算符基本上一樣,唯一的差別就是兩個操作數對應位間如果都不為0則結果的相應位為1,否則為0。使用的情形不再重述,語法如下:
var result = 操作數1 | 操作數2;
例如2的二進制碼為10,3的二進制碼為11。2和3作位或運算則得3,因為2的第一位和3的第一位至少有一個為1。因此結果的第一位為1,2的第2位和3的第2位至少有一個為1,則結果的第2位也為1。因此計算結果為3,即二進制碼11。
提示:注意結合位與運算符的特點,這兩者正好互補。
4.9.3 位異或運算符
位異或運算符“^”的作用是當兩個操作數對應位不相同時結果的相應位即為1,否則為0。應用的情形與位與、位或相同,僅僅存在功能上的區別。人們通常使用該運算符測試兩個位是否相同,語法如下:
var result = 操作數1 ^ 操作數2;
例如,2與的二進制碼為10,1的二進制碼為01。2與1作位異或運算將得到3,因為兩者的第一二位正好不相同,因此得到二進制碼11,也就是十進行數字3。通常,位異或用在信息加密解密的場合,因為A和B位異或運算得C,C和B位異或運算得A。
【范例4-21】妙用位異或運算實現信息加密解密。為了不使密碼“123456”以明文的形式存放,現將其加密,密鑰為“666666”,輸出加密后和解密后的密碼。如示例代碼4-21所示。
示例代碼4-21
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var user = "foxun"; // 用戶名 04 var password = 123456; // 密碼,需要對其加密 05 var key = 666666; // 加密密鑰 06 var codedpassword = password ^ key; // 將明文密碼123456加密 07 alert( "加密后的密碼:" + codedpassword ); // 輸出加密后的密 08 codedpassword ^= key; // 將加密后的密碼解密 09 alert( "解密后的密碼:" + codedpassword ); // 輸出解密后的密碼 10 --> 11 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,結果如圖4-22、圖4-23所示。

圖4-22 加密后密碼

圖4-23 解密后密碼
【代碼解析】該代碼段第3~5行設定了用戶信息,包括用戶名、密碼和加密密鑰。第6行將密碼和密鑰進行位異或運算,得到加密后的密碼。第7行輸出加密后的密碼,以表示加密成功。第8行將加密后的密碼與密鑰進行位異或運算,實現解密。第9行將解密后的密碼輸出,表示解密成功。
4.9.4 位非運算符
位非運算符“~”實現對操作數按位取反運算,屬于單目運算符。操作數可以是任意JavaScript類型的常量或變量。運算的過程和結果如圖4-24所示。

圖4-24 位非運算符示意圖
使用語法如下:
result = ~操作數;
通過大量的實驗證明,JavaScript中對數據的位非運算有其獨特的規律。看起來并不完全等同于其他編程語言所進行的位級運算,對于字符串數據,按位取反后值為-1。對布爾值true和false取反分別得-2和-1,對數值數據+N得-(N+1),-N得N-1。下面編寫程序逐一測試。
【范例4-22】測試按位反運算符,尋找其計算規律,如示例代碼4-22所示。
示例代碼4-22
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var msg = "正數取反:"; 04 for( i = 0; i<50; i++ ) // 連續對0到49進行位取反,并逐一添加輸出字符串 05 { 06 msg += i + "=>" + (~i) + " "; // 添加取反后的值到字符串中 07 } 08 msg += "\n負數取反:"; 09 for( i = -50; i<0; i++ ) // 連續對-50到-1進行位取反,并逐一添加到輸出字符串 10 { 11 msg += i + "=>" + (~i) + " "; // 添加取反后的值到字符串中 12 } 13 msg += "\n布爾值取反:"; 14 var b1 = true; //對布爾值true和false按位取反,并添加到輸出字符串 15 msg += b1 + "=>" + (~b1) + " "; // 添加取反后的值到字符串中 16 var b2 = false; 17 msg += b2 + "=>" + (~b2) + " "; // 添加取反后的值到字符串中 18 msg += "\n字符串取反:"; 19 var name = "Bob"; // 對布爾值字符串按位取反,并添加到輸出字符串 20 msg += "\"" + name + "\"" + "=>" + (~name) + " "; 21 alert( msg ); // 輸出 22 --> 23 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,結果如圖4-25所示。

圖4-25 各種數據的位反結果
【代碼解析】該代碼段第3~12行對數值數據的正負數分別按位取反,以尋找其中規律。第14~17行對布爾值進行位取反,通過輸出結果發現布爾值數據在取反前事先轉換為數值型。第19行對字符串對象按位取位,得到“-1”,說明對象按位取反皆為“-1”,對象特性值則不然。
4.9.5 左移運算符
內存單元中的二進制數據按位作前述的與、或、反的運算可以形成新的數據。通過整體向左向右移動也可以形成新的數據。左移位運算符“<<”,實現整體向左移動低位補0的功能,屬于雙目運算符,語法如下:
result = 操作數1 << 操作數2
操作數1向左移動用操作數2表示的位數,例如“50<<3”可以將數據1的二進制位序列整體向左移動3位,代碼如下所示。
var bitSet = 50; bitSet = bitSet<<3;
50的二進制碼110010向左移3位后為110010000,等于十進制數400。向左移n位相當于原數乘以2n,執行的過程如圖4-26所示。

圖4-26 左移位示意圖
提示:移位時一定考慮因為符號位的移動而帶來的影響。
4.9.6 帶符號右移運算符
前面講過左移位運算符,與之對應的是右移位運算符。右移位包括帶符號位右移和無符號位右移,共同之處是都移動給定的位數,不同之處是高位的處理方式不同。進一步學習移位操作之前,先來了解計算機中表示有符號數的方法。
通常,數據存儲于計算機內存單元中。對于有符號數,除了保存表示數據大小的二進制位外,還使用一位來表示數據的符號。一般在最高位使用“1”表示負數,“0”表示正數。例如“-10”的二進制碼為11100,“+10”的二進制碼為01100。最左邊那位就是符號位,當進行右移位運算時將面臨符號位如何處理的問題。
當移動的是有符號數,左邊空出的位用數的符號位填充。向右移動超出的位將被丟棄,稱為帶符號右移位操作。其運算符為“>>”,使用語法如下:
result = 操作數1>>操作數2;
兩個操作數可以是任意JavaScript類型的變量或常量,操作數1的二進制位向右移用操作數2表示的位數。代碼如下所示。
var number = -5; number = number>>2;
有符號數-5的二進制碼為1101,右移2位后變為11;再使用符號位對左邊空出的兩位進行填充,因此最后變為1111。
提示:進行移位運算后數據的值將被更新,在位級控制應用中的意義更大,在類似JavaScript這種自動化腳本語言中并不常用。
4.9.7 高位補0右移運算符
前面已經提及右移運算時符號位的處理問題,那是針對有符號數的情況。當數是無符號數時,右移后在左邊空出的位上填充0,稱為無符號右移位。對應的運算符是“>>>”,使用語法如下:
result = 操作數1>>>操作數2;
操作數可以是任意類型的變量或常量,操作數1的二進制碼將被右移用操作數2表示的位數,左邊空出的位用0填充。右邊超出的位被丟棄,例如無符號數5的二進制碼為101,向右移2位后為001,也就是十進制數1。運算過程與有符號差不多一樣,讀者學習時將二者聯系起來。
4.10 其他運算符
前面講過操作數、算術運算符和邏輯運算符等,這些是程序設計語言最基本的要素。但是程序設計語言不是純粹的數學計算和邏輯推理。因此程序設計語言還需要配備一些特殊的運算符用在一些特殊的場合。本節將介紹條件運算符、new運算符、void運算符、typeof運算符、點運算符、數組存取運算符、delete運算符、逗號運算符、this運算符等。這些運算符相當重要,希望讀者熟練掌握。
4.10.1 條件運算符
編程經常遇到根據條件在兩個語句中執行其一的情況,用一個if語句顯得麻煩。為簡化程序的編碼JavaScript提供了條件運算符,可以根據條件在兩個語句間選擇一個來執行。使用符號“?:”,屬于三目運算符,語法如下:
條件表達式 ? 語句1:語句2
參數說明:
● 條件表達式,結果被作為布爾值處理的表達式。
● 語句1,如果條件表達式返回true則執行之。
● 語句2,如果條件表達式返回false則執行之。
條件運算符通常用于組織復雜的表達式。代碼如下所示。
var hours = 8; // 已經8點 var msg = "現在是" + ( ((time<=12)&&(time>=6)) ? "上午":"不是上午" );
上述字符串表達式中使用了條件運算符,其判斷當前時間而確定將哪個字符參與字符串連接運算。使用條件運算符大大方便了代碼的編寫。
提示:盡管條件運算符在一些場合表現得很好,但也不能濫用。為了代碼有更好的可讀性,表達式不宜過于復雜。
4.10.2 new運算符
JavaScript是基于對象的語言,本書第2章在講解有關復合數據類型的內容時已經創建了大量的對象。創建對象的一種方式是直接使用new運算符,該運算符創建一個類的實例對象。語法如下:
new constructure( [args,[…]] );
參數說明:
● constructure:是類的構造函數,用于構造對象。
● args:是傳遞給構造函數的參數,可選項。
例如,創建一個字符串對象的代碼如下:
var myName = new String( "Foxsir" );
變量myName引用了新建的String對象,常量“Foxsir”被作為參數傳遞給String類的構造函數String( arg )。使用new運算符創建的對象,若要刪除須對引用對象的變量賦null值。
4.10.3 void運算符
前面講過的表達式都可以返回一個值,然而有些地方卻不需要返回值。此時可以使用void運算符來避免表達式返回值,void運算符可以帶來靈活的設計。例如將JavaScript代碼寫到IE地址欄中并執行,為了使當前文檔內容不至于被清除,地址欄中的代碼不能有返回值。
【范例4-23】使用IE地址欄來執行簡單的JavaScript代碼,使之打開微軟公司的網站首頁(http://www.microsoft.com)。如示例代碼4-23所示。
示例代碼4-23
01 javascript:void( window.open("http://www.microsoft.com") ); // 在瀏覽器地址欄中執行
【運行結果】打開網頁文件運行程序,結果如圖4-27所示。

圖4-27 在地址欄中執行JavaScript代碼
【代碼解析】程序僅有一行代碼,而且寫到IE地址欄中。windows對象的open方法可以打開一個新窗口,并加載指定地址的文件。open方法返回一個值引用新打開的窗口,如果不使用void運算符屏蔽返回值,當前窗口的內容將被清除并且寫入“[Object]”。
提示:void可以讓表達式被執行而結果被忽略,這個特性在一些場合非常有用。
4.10.4 類型檢測運算符
因為JavaScript中每一個數據都屬于一種數據類型,通過使用typeof運算符即可獲得數據的類型名。typeof返回一個表達式的值的類型名,在一些需要得知對象的類型的場合非常有用。使用語法如下:
typeof( 表達式 );
typeof返回6種可能的值,分別為“Number”、“String”、“Boolean”、“Object”、“Function”和“undefined”。例如求一個字符串對象的類型,代碼如下所示。
var message = "歡迎您訪問本站"; // 消息字符串 var type = typeof(message ); // 取變量類型名
4.10.5 對象屬性存取運算符
對象屬性存取運算符在一些書籍中稱為點號運算符,使用符號“.”表示。其作用是讀取對象的屬性,或者保存值到對象的屬性,或者調用對象的方法。使用語法如下:
對象名.屬性名或方法名 類名.方法名
第一種是調用實例對象的屬性或方法。對象名必須是有效的對象引用,屬性名或方法必須是對象所擁有的特性。第二種是調用類的靜態方法,靜態方法是所有對象共有的,類無須實例化即可使用的方法。例如為了求“楊宗楠”的名字長度,可以使用如下代碼。
01 var nameYZN = "楊宗楠"; // 創建一個字符串對象 02 var len = nameYZN.length; // 調用String類對象的length屬性 03 var xing = nameYZN.charAt(0); // 調用String類對象的charAt方法,取得宗楠的姓 04 var unicodeOfYang=String.fromCharCode(26472);// “楊”的unicode編碼為26472
上述代碼演示了如何使用點號運算符調用對象的屬性和方法,以及如何調用類的靜態方法。第4行直接調用String類的靜態方法fromCharCode,將unicode碼26472轉為“楊”字。
4.10.6 數組存取運算符
數組以元素為單位保存數據,讀取其中的數據時需要讀出元素。JavaScript提供“[]”運算符用于存取數組元素,方括號中是要存取的元素的下標。這個運算符大大方便了數組的編程,使用語法如下:
數組名[下標]
通常使用一個循環將下標從0遞增到數組的最大下標,結合“[]”運算符即可遍歷數組,下面舉例以加深印象。
【范例4-24】現在5個學生名字,存于數組中。要求將5個名字按存放的順序輸出,如示例代碼4-24所示。
示例代碼4-24
01 <script language="javascript"> // 腳本開始 02 <!-- 03 var nameList=new Array("Tom","Lisley","Petter","ZongNanYang","Lily", "Jackson" ); // 名單 04 for( index in nameList ) // 遍歷名單 05 { 06 document.write( nameList[index] + "<br>" ); //使用“[]”運算符讀取數組元素的內容 07 } 08 --> 9 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,結果如圖4-28所示。

圖4-28 輸出名字
【代碼解析】該代碼段第3行創建一個數組用于保存學生的名字,第6行在循環語句中使用“[]”逐一提取數組元素。
4.10.7 delete運算符
要刪除使用new運算符創建的對象需要將對象的引用賦值null,當引用為0時系統自動收回對象所占的資源。delete運算符則可以刪除對象的一個屬性或數組的一個元素,JavaScript對象的屬性可以動態添加。對于動態添加的屬性可以用delete運算符將其刪除,與其他面向對象的編程語言不同。
【范例4-25】用一個對象表示一個學生,為其動態添加姓名、性別和年齡等屬性。如示例代碼4-25所示。
示例代碼4-25
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var student = new Object(); // 創建一個對象表示學生 04 student.name = "Tom"; // 為學生對象添加“名字”屬性 05 student.age = 20; // 添加“年齡”屬性 06 student.sex = "男"; // 添加“性別”屬性 07 // 輸出學生的三個屬性 08 document.write( "<li>" + student["name"] + ":" + student["sex"] + " " + student["age"] ); 09 delete student.age; // 刪除學生的“年齡”屬性 10 // 再次輸出全部屬性作對比 11 document.write( "<br>刪除了age屬性<br><li>" + student["name"] + ":" 12 + student["sex"] + " " + student["age"] ); 13 --> 14 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,結果如圖4-29所示。

圖4-29 輸出人物信息
【代碼解析】該代碼段第3~6行創建一個對象表示學生,并為之添加了三個屬性。第8行輸出學生對象的三個屬性,第9行使用delete運算符將學生對象的age屬性刪除。第11、12行試圖再次輸出學生的三個屬性,但age屬性已經不存在了,因此輸出為undefined。
4.10.8 逗號運算符
逗號運算符使用符號“,”,作用是使其兩邊的表達式按左到右的順序被執行,并返回最右邊表達式的值。使用語法如下:
表達式1,表達式2
逗號運算符常用在for循環中。示例如下:
01 var j = 0; // 取0 02 for( i = 0; i<10; i ++, j++ ) // 循環10遍 03 { 04 j *= i; // 累乘 05 }
每次for循環執行到末端時,一般只允許一個表達式被執行。而“,”運算符則可以使兩個表達式得到執行,突破了該限制。
4.10.9 函數調用運算符
函數調用運算符“call”,作用于Function對象。主要功能是調用對象的一個方法,并以另一個對象作替換為當前對象,以改變this指針的指向。JavaScript函數和對象方法的調用通常發生于一個運行時上下文中,一般為Global對象上下文。但當前執行上下文可以更改,使用call運算符即可達到目的。語法如下:
對象名.call( [ thisObj , [ arg1, [ arg2, [ argn, […] ] ] ] ] )
參數說明:
● 對象名:為一個有效的Function對象。
● thisObj:是即將換為當前上下文對象的對象引用,可選,當省略時自動設置為Global對象。
● arg:是傳遞給Function對象的參數,可選。
使用call運算符可以改變函數執行上下文,這是個特性在一些特殊場合非常有用,下面舉例說明以加深理解。
【范例4-26】現有兩個學生對象,他們擁有值不相同的同種屬性(姓名和年齡)。要求將學生的姓名和年齡輸出,如示例代碼4-26所示。
示例代碼4-26
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 function showStudentInfo() // 定義一個函數,用于輸出學生信息 04 { 05 // 輸出this指向的對象的name、age成員 06 document.write( "<li>" + this.name + " " + this.age + "<br>" ); 07 } 08 function Student( _name, _age ) // 定義Student類的構造函數 09 { 10 this.name = _name; // 添加屬性 11 this.age = _age; 12 } 13 var stu1 = new Student( "Tom", 20 );// 創建兩個學生類實例 14 var stu2 = new Student( "Lily", 21 ); 15 showStudentInfo.call( stu1 ); // 不同的上下文中調用showStudentInfo 16 showStudentInfo.call( stu2 ); 17 --> 18 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,結果如圖4-30所示。

圖4-30 學生名字和年齡
【代碼解析】該代碼段第3~7行定義一個函數,用于輸出this指針指向的對象的name和age兩個屬性。第8~12行定義一個學生類構造函數,用于創建學生對象。第13、14行創建了兩個學生對象,第15、16行使用call運算符調用函數showStudentInfo。此時執行上下文分別改變為stu1和stu2,目的是重設函數對象showStudentInfo的this指針的指向。
提示:call運算符提供了一種很好的改變執行上下文的機制,使用它可以做出巧妙的設計,讀者請多加練習。
4.10.10 this運算符
“this”嚴格地說是一個關鍵字,也可以理解為運算符。面向對象的編程中要引用當前對象, this運算符可以返回當前對象的引用。this通常用在對象構造函數中,用來引用函數對象本身。語法如下:
this.屬性名或方法名
給自定義對象添加屬性時,在類構造函數中使用this運算符。例如創建一個汽車類,給汽車添加最大速度和載重屬性,代碼如下所示。
01 function Car ( _rateMax, _ carryingCapacity ) // 構造函數 02 { 03 this. rateMax = _rateMax; // 添加屬性:極速 04 this. carryingCapacity = _carryingCapacity;// 添加屬性:最大載重 05 }
4.11 掌握運算符的優先級
前面的內容講解了JavaScript中的表達式、操作數和運算符,表達式由運算符和操作數構成。到目前為止,讀者所接觸過的表達式都比較簡單,但表達式可以是很復雜的復合表達式。在一個復雜的表達式中,多個運算符結合在一起,勢必會出現計算的先后順序問題。
JavaScript中的運算符優先級是一套規則。該規則在計算表達式時控制運算符執行的順序。具有較高優先級的運算符先于較低優先級的運算符得到執行。同等級的運算符按左到右的順序進行。歸納總結如表4-1所示。
表4-1 運算符優先級(從高到低)

由表4-1可以看出,運算符比較多,記住各運算符的優先級并不容易。因此編程時一般都使用圓括號“()”來決定表達式的計算順序,示例如下:
((A + B)&C)>>3
在這里圓括號意義上完全等同于數學表達式里的圓括號,即括號內的優先級最高,最先得到計算。上述代碼執行順序為:A加上B,再將結果與C做位與運算,最后帶符號右移3位。下面舉例說明運算符的優先級。
【范例4-27】編程測試“+、-、×、÷”運算符的優先順序,求表達式“1+2/5-0.1*5”的值并輸出,如示例代碼4-27所示。
示例代碼4-27
01 <script language="javascript"> // 腳本程序開始 02 var result1 = 1+2/5-0.1*5; // 默認優先級順序 03 var result2 = ((1+2)/5-0.1)*5; // 用小括號改變優先級 04 document.write("<b>運行符優先級</b>"); // 輸出標題 05 document.write("<li>1+2/5-0.1*5=" + result1 ); // 輸出表達式1的結果 06 document.write("<li>((1+2)/5-0.1)*5=" + result2 ); // 輸出表達式2的結果 07 </script> <!--腳本程序結束-->
【運行結果】打開網頁運行程序,運算結果如圖4-31所示,對比其中兩個不同表達式的結果。

圖4-31 對比兩個表達式的結果
【代碼解析】代碼段第2、3行分別定義兩個算術表達式,第一個表達式使用默認運算符優先級。其運算順序按JavaScript的規定,順序為“/、+、*、-”。第二個表達式使用小括號強制改變計算優先級,順序為“+、/、-、*”。
提示:編程時通常使用小括號決定計算優先級,而不用背優先級表。
4.12 小結
本章講解了JavaScript中的表達式、操作數、算術運算符、關系運算符和邏輯運算符等內容;介紹了數在計算機中的表示以及如何進行位級運算,使用new運算符可以創建類的對象;刪除對象動態添加的屬性可以使用delete運算符。
instanceof返回一個布爾值表示該對象是否是某個類的實例,typeof則返回一個對象所屬的類型名稱。JavaScript運算符種類繁多,各類運算符優先級各不相同,圓括號極大地方便了代碼的書寫。如果讀者對本章內容還有什么疑問,可以參考《JavaScript實例自學手冊:通過486個例子掌握Web開發捷徑》(電子工業出版社,吳雪)和《完全手冊:HTML+CSS+JavaScript實用詳解》(電子工業出版社,葉青)等書籍。
4.13 習題
一、常見面試題
1.表達式null === undefined的運算結果是否為真?
【解析】本題考查的是常見表達式的運算,只要掌握了表達式的基本概念,本題不難解答,答案是結果為真。
2.說出JavaScript運算符的種類。
【解析】本題考查的是對JavaScript運算符的掌握程度。
【參考答案】算術運算符、關系運算符、字符串運算符、邏輯運算符、賦值運算符、位運算符等。
二、簡答題
1.什么是表達式?它有什么作用?
2.列舉出JavaScript中的運算符。
三、綜合練習
1.人們在網絡上傳送敏感信息時通常需要加密處理,以防被他人竊取。現在要求編寫一個信息加密解密的應用程序,可以將數據信息加密成不可閱讀識別的數據,同時又能將加密后的數據解密還原。
【提示】加密解密可以使用位異或運算實現,因為A與B異或得到C,C與B異或可以得到A。因此B將成為密鑰。字符串對象的charCodeAt方法可以取得一個字符的unicode編碼,可以對此編碼進行加密運算。fromCharCode方法可以將一個unicode編輯還原為字符,因此可以從加密解密后的unicode碼串還原字符串。參考代碼如下:
01 <body> <!--文檔體--> 02 <script language="javascript"> // 腳本程序開始 03 <!-- 04 var msgCoded; // 加密后的串 05 var msgEncoded; // 解密后的串 06 function CodeAndEncode( pkey, date ) // 加密解密函數 07 { 08 var codedStr = ""; // 已加密或解密的字符序列 09 for( i = 0; i<date.length; i++ ) // 對信息串逐個加密 10 { 11 var dateCoded; // 已加密或解的字符的unicode編碼 12 for( j = 0; j<pkey.length; j++ ) // 密鑰串的每個字符與串中當前字符進行位異或 13 { 14 var keyCoded = pkey.charCodeAt( j ); // 從密鑰串中提取一個字符的unicode編碼 15 var dateCoded = date.charCodeAt(i) ^ keyCoded; // 異或運算 16 } 17 codedStr += String.fromCharCode( dateCoded ); 18 } 19 return codedStr; // 返回信息串 20 } 21 function BtnCode_onclick() // “加密”按鈕單擊事件處理程序 22 { 23 var date = TextArea1.value; // 提取要加密的文本 24 var key = Password1.value; // 提取密鑰 25 msgCoded = CodeAndEncode( key, date ); // 加密 26 TextArea1.value = msgCoded; // 在文本域中顯示加密結果 27 } 28 function BtnEncode_onclick() 29 { 30 var date = TextArea1.value; // 提取要解密的文本 31 var key = Password1.value; // 提取密鑰 32 msgEncoded = CodeAndEncode( key, date ); // 解密 33 TextArea1.value = msgEncoded; // 在文本域中顯示解密后的文本 34 } 35 --> 36 </script> <!--腳本程序結束--> 37 <!-用戶界面,設置一個文本域、一個文本編輯框、兩個按鈕--> 38 <textarea id="TextArea1" style="width: 331px; height: 211px"></ textarea> <br /> 39 密鑰: 40 <input id="Password1" type="password" /> 41 <input id="BtnCode" type="button" value="加密" onclick="return BtnCode_ onclick()" 42 style="width: 57px" /> 43 <input id="BtnEncode" style="width: 55px" type="button" value="解密" 44 onclick="return BtnEncode_onclick()" /> 45 </body> <!--文檔體結束-->
【運行結果】打開網頁文件運行程序,加密結果如圖4-32所示,解密結果如圖4-33所示。

圖4-32 加密后的結果

圖4-33 解密后的結果
2.對數個學生的名字進行排序并輸出,排序前的順序為:“Tom”、“Petter”、“Jim”、“Lily”。
【提示】可以使用數組作為數據的容器,使用本章講過的in運算符結合for循環遍歷數組;再使用關系運算符作字符串升降序比較,參考代碼如下:
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var students = new Array( "Tom", "Petter", "Jim", "Lily" );// 學生名字 04 document.write( "排序前:" + students ); // 輸出排序前的名字序列 05 for( n in students ) // 在for語句中使用in運算符遍歷數組 06 { 07 for( m in students ) // 逐一比較 08 { 09 if( students[n] < students[m] ) // 使用“<”運算會進行升序比較 10 { 11 var temp = students[n]; // 交換數組元素內容 12 students[n] = students[m]; 13 students[m] = temp; 14 } 15 } 16 } 17 document.write( "<br>" ); // 輸出換行 18 document.write( "排序后:" + students ); // 輸出排序后的名字序列 19 --> 20 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,運行結果如圖4-34所示。

圖4-34 運行結果
四、編程題
1.編一程序計算8*x*x+(x+y)*(3*x-8)的值。
【提示】本題可以設置幾個變量,然后按照運算符的優先級進行運算即可。
2.編寫一程序計算表達式((( b + c ) * 30 + 70 * ( d-3 ) ) * e)%7的值。
【提示】本題與上題類似,只是需要多設置幾個變量,然后即可按照相同方法得到計算結果。
- Mastering Spark for Data Science
- Dreamweaver 8中文版商業案例精粹
- 大數據技術入門(第2版)
- JBoss ESB Beginner’s Guide
- 數據掘金
- 貫通Java Web開發三劍客
- 突破,Objective-C開發速學手冊
- 電腦日常使用與維護322問
- 零起點學西門子S7-200 PLC
- R Machine Learning Projects
- Working with Linux:Quick Hacks for the Command Line
- INSTANT VMware vCloud Starter
- 三菱FX/Q系列PLC工程實例詳解
- 計算機應用基礎實訓(職業模塊)
- Hands-On Deep Learning with Go