- 21天學通JavaScript
- 顧寧燕等編著
- 4572字
- 2018-12-29 13:30:26
第3章 變量和常量
上一章講解了數據類型,與數據直接相關的就是變量。變量和常量是每種程序設計語言不可缺少的組成部分。變量和常量都與數據存儲相關,變量是程序中其值可以被改變的內存單元。常量也存儲于內存中,但其值不可以改變,有的常量作為立即操作數,并不存在于內存中,相關細節超出了本書的范圍,在此不做講述。
● 理解和掌握變量的定義和使用方法
● 理解和掌握常量的特點及其使用方法,簡化程序的編碼
● 加深對數據類型的理解
以上幾點是對讀者在學習本章內容時所提出的基本要求,也是本章希望能夠達到的目的。讀者在學習本章內容時可以將其作為學習的參照。
3.1 常量
程序一次運行活動的始末,有的數據經常發生改變,有的數據從未被改變,也不應該被改變。常量是指從始至終其值不能被改變的數據,JavaScript中的常量類型主要包括字符串常量、數值常量、布爾常量、null和undefined等。常量通常用來表示一些值固定不變的量,比如圓周率、萬有引力常量等。
3.1.1 常量分類
在數學和物理學中,存在很多種常量,它們都是一個具體的數值或一個數學表達式。然而在編程語言中基于數據類型的分類,常量包括字符串型、布爾型、數值型和null等,定義形式如下:
"今天天氣真好!"; // 字符串常量 1; e1; 077; // 數值型常量 true; false; // 布爾型常量
其中,字符串常量的值可以是任意的字符串。布爾型常量只有兩種值,即true和false。數值型常量為合法的數值數據,可以使用十進制、八進制和十六進制形式。
3.1.2 使用常量
常量直接在語句中使用,因為它的值不需要改變,所以不需要再次知道其存儲地點。下面通過舉例演示常量的使用方法。
【范例3-1】練習字符串常量、布爾型常量和數值常量的使用,將八進制、十六進制數輸出為十進制數,如示例代碼3-1所示。
示例代碼3-1
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 document.write( "<li>JavaScript編程,樂趣無窮!<br>" ); //使用字符串常量 04 document.write( "<li>" + 3 + "周學通JavaScript!" ); //使用數值常量3 05 if( true ) // 使用布爾型常量true 06 { 07 document.write( "<br><li>if語句中使用了布爾常量:" + true ); // 輸出提示 08 } 09 document.write( "<li>八進制數值常量011輸出為十進制:" + 011 ); // 使用八進制常量和十進制常量 10 document.write( "<br><li>十六進制數值常量0xf輸出為十進制:" + 0xf ); 11 --> 12 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖3-1所示。

圖3-1 輸出各種進制數
【代碼解析】該代碼段第3行直接在document對象的write方法中使用字符串常量。第4行在document對象的write方法中使用數值常量3,write方法需要輸入的是字符串參數,則數字3被隱式轉換為字符串“3”。第5行在if語句塊中使用布爾型常量true。第9~10行輸出時八進制和十六進制數均被轉換為十進制后再轉換為字符串型。
提示:JavaScript是一門腳本語言,典型的弱類型語言,沒有如C++等語言的類型機制,也沒有const修飾符將變量定義常量的能力。
3.2 變量
一般情況下,程序運行時的計算結果、用戶從外部輸入的數據等都需要保存。對于少量的數據,計算機將其保存到系統內存中。為了方便程序代碼操作這些數據,編程語言使用變量來引用內存存儲單元,通過上一節的學習,讀者了解到變量是程序語言最基本的要素,本節將對其進行全面的講解。
3.2.1 什么是變量
顧名思義,變量是指在程序運行過程中值可以發生改變的量,更為專業的說法就是指可讀寫的內存單元??梢孕蜗蟮貙⑵淅斫鉃橐粋€個可以裝載東西的容器,變量名代表著系統分配給它的內存單元,如圖3-2所示。

圖3-2 內存單元模型示意圖
3.2.2 如何定義變量
JavaScript中,用如下方式定義一個變量。
var 變量名 = 值; // 定義變量 變量名 = 值; // 賦值
var是JavaScript中定義變量的關鍵字,也可以忽略此關鍵字。用var關鍵字聲明變量時也可以不賦初始值。
var 變量名; // 定義變量
JavaScript的變量在聲明時不需要指定變量的數據類型,程序運行時系統會根據變量的值的類型來確定變量的類型。變量的類型決定了可對變量數據進行的操作,比如在C++中,一個int型變量在X86系列32位CPU上占4個字節。對變量的操作即是針對其所占用的4個字節單元進行,以int方式的訪問即一次可訪問4個字節單元。此處介紹C++的int類型目的是幫助讀者增強對變量數據類型的理解,JavaScript是弱類型語言,不需要過分強調數據類型。
下面分別定義各種類型變量。
● 字符串型
var str = "JavaScript編程,簡單容易!"; // 定義字符串變量
● 布爾型
var b = true; // 定義布爾變量
● 數值型
var n = 10; // 數值型變量
● 復合型
var obj = new Object(); // 復合型變量
復合型是指用戶自定義類型或JavaScript內置復合類型,比如數組。在應用中復合型的使用非常廣泛,本書后面為復合數據類型安排了專門的章節講解。
變量的使用形式不外乎兩種情況,一種是讀取其內容,另一種是改寫其值。變量的內容一經改寫后一直有效,直到再次改寫或生命周期結束。
【范例3-2】練習變量的定義和使用。定義一組各種常見類型的變量并輸出其值,如示例代碼3-2所示。
示例代碼3-2
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var str = "21天學通JavaScript!"; // 定義一個字符串變量 04 var b = true; // 定義一個布爾型變量 05 var n = 10; // 定義一個數值型變量 06 var m; // 聲明一個變量m,其類型未知 07 var o = new Object(); // 定義一個Object類型變量o 08 p = new Object(); // 定義一個Object類型變量p 09 document.write( str ); // 分別使用write在當前文檔- 10 document.write( "<br>" ); 11 document.write( b ); // 對象中輸出各變量的內容 12 document.write( "<br>" ); // 輸出換行標簽 13 document.write( n ); 14 document.write( "<br>" ); // 輸出換行標簽 15 document.write( m ); 16 document.write( "<br>" ); // 輸出換行標簽 17 document.write( o ); 18 document.write( "<br>" ); // 輸出換行標簽 19 document.write( p ); 20 document.write( "<br>" ); // 改寫各變量的值 21 str = "這是一個字符串"; 22 b = false; 23 n = 20; 24 m = 30; // 改變變量o的引用,指向一個新建的數組 25 o = new Array( "data1", "data2" ); 26 document.write( "<font color=red><br>" ); 27 document.write( str ); // 分別使用write在當前文檔- 28 document.write( "<br>" ); // -對象中輸出各變量的內容 29 document.write( b ); 30 document.write( "<br>" ); // 輸出換行標簽 31 document.write( n ); 32 document.write( "<br>" ); // 輸出換行標簽 33 document.write( m ); 34 document.write( "<br>" ); // 輸出換行標簽 35 document.write( "<br>數組o的數據為:" ); 36 document.write( o ); 37 document.write( "<br>數組o的長度為:" + o.length ); 38 document.write( "<br></font>" ); 39 var pp; 40 document.write( pp ); // 輸出未定義變量pp 41 var pp = 20; 42 --> 43 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,結果如圖3-3所示。

圖3-3 輸出變量的類型和值
【代碼解析】該代碼段演示了各種變量的定義方式。第3~5行定義三個不同類型的變量,定義時就已經賦予初始值,值的類型確定后變量的類型即可確定。第9~20行分別輸出各個變量中的值,發現m輸出為undefined。與m相關的“不明確”主要包含兩方面的含義,一是數據類型不明確,即未確定;其次是變量的值未確定。
第17~19行輸出的復合數據類型Object對象的值時僅輸出其類型名稱。第21~25行改寫部分變量的值,第26~40行再次輸出所有變量的值,目的在于與前面對照比較。輸出數組對象時,將合并其中各元素的值作為整體輸出。
提示:因為JavaScript程序的執行是順序解釋執行,所以變量必須先聲明才能使用,聲明的位置必須在使用變量的語句的前面。
3.2.3 變量的命名
JavaScript變量的命名必須以字母或下畫線開始,后可跟下畫線或數字,但不能使用特殊符號。以下命名是合法的。
name // 合法的變量名 _name // 合法的變量名 name10 // 合法的變量名 name_10 // 合法的變量名 name_n // 合法的變量名
以下命名方式是非法的。
12name // 不合法的變量名 $name // 不合法的變量名 $#name // 不合法的變量名
JavaScript對標識符大小寫敏感,以下是兩個不同的變量名。
name // 變量 Name // 變量
筆者建議為變量取有意義的名稱,便于代碼的閱讀。書寫時可用“匈牙利”命名習慣,比如字符串的變量名前加“s”,整型變量名前加“n”,布爾變量名前加“b”等。示例如下:
var sMyStr = "this is a string"; // 字符串變量 var nIndex = 0; // 數值型變量 var bStored = true; // 布爾型變量
JavaScript內置對象的方法命名規律為第一個單詞全小寫,后面每個單詞首字母大寫。示例如下:
isNaN // 規范的命名 cookieEnabled // 規范的命名
【范例3-3】定義兩個數字變量,分別賦予10,20初始值。輸出兩個變量的值,再交換兩個變量的值后輸出,熟悉匈牙利命名規范,如示例代碼3-3所示。
示例代碼3-3
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var nA = 10; // 定義兩變量并賦初始值 04 var nB = 20; 05 document.write( "交換前<br> " ); // 輸出交換前兩變量的值 06 document.write( "<li>nA = " + nA ); // 輸出nA 07 document.write( "<li>nB = " + nB ); // 輸出nB 08 var nTemp = nA; // 交換兩變量的值 09 nA = nB; 10 nB = nTemp; 11 document.write( "<br>交換后<br> " ); // 輸出交換后兩變量的值 12 document.write( "<li>nA = " + nA ); // 輸出nA 13 document.write( "<li>nB = " + nB ); // 輸出nB 14 --> 15 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖3-4所示。

圖3-4 交換前后的變量值
【代碼解析】第3、4行定義兩變量并賦值,第6、7行分別輸出變換前的變量內容。第8~10行定義一個“臨時”變量參與交換nA和nB的值。第12、13行輸出nA和nB。
提示:良好的書寫習慣可大大減少代碼后期維護的工作量?!靶傺览泵ú皇怯残砸幏?,原為微軟的一個優秀程序員所創,但良好的習慣值得學習和效仿。
3.2.4 變量的作用范圍
作用域是指有效范圍,JavaScript變量的作用域有全局和局部之分。全局作用域的變量在整個程序范圍都有效,局部作用域指作用范圍僅限于變量所在的函數體。JavaScript不像其他語言那樣有塊級作用域。變量同名時局部作用域優先于全局作用域。
【范例3-4】編寫程序,測試變量的作用范圍的優先級,如示例代碼3-4所示。
示例代碼3-4
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var nA = 10; // 定義全局變量nA 04 function func() 05 { 06 var nA = 20; // 定義局部變量nA并輸出 07 document.write( "<li>局部作用范圍的nA:" + nA ); // 輸出nA 08 } 09 func(); // 調用函數func 10 document.write( "<li>全局作用范圍的nA:" + nA ); // 輸出全局nA 11 --> 12 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖3-5所示。
【代碼解析】第3行定義的變量nA,其有全局作用域。第4~8行定義一個函數,其內定義一個變量nA,與全局變量nA同名。第9行調用函數func,以輸出局部變量nA。第10行輸出全局變量nA,目的與func輸出的局部變量作比較。

圖3-5 輸出同名變量
注意:當局部變量與全局變量同名時,局部變量要使用var關鍵字。
3.2.5 變量的用途
變量主要用于存儲數據,比如計算的結果、存儲用戶輸入的數據等。一部分變量作為對象的引用,通過變量來操作對象的內容或調用對象的方法,下面舉例說明。
【范例3-5】創建一個數組,其內容包含站點用戶中不同類型角色的名稱,如示例代碼3-5所示。
示例代碼3-5
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var actorAry = new Array( "超級管理員", "管理員", "VIP 用戶", "普通用戶" ); // 角色數組 04 document.write("用戶角色:"); // 標題 05 for( n in actorAry ) // 遍歷數組 06 { 07 document.write( "<li>" + actorAry[n] ); // 通過變量actorAry操作角色數組 08 } 09 --> 10 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖3-6所示。

圖3-6 輸出數組元素
【代碼解析】第3行定義變量actorAry,其引用新建的數組。第5~8行輸出數組各元素。變量actorAry將代表一個數組對象,直到其被賦予新的值。通過actorAry可以操作其代表的數組的數據或調用數組的方法。
3.3 JavaScript關鍵字詳解
關鍵字為系統內部保留的標識符,其用途特殊,用戶的標識符不能與關鍵字相同。下面列出JavaScript中常見關鍵字,如表3-1所示,可供讀者參照。
表3-1 JavaScript常見關鍵字

注意:上表列出了常用的關鍵字,其中大部分內容讀者現在不必知道,以后用到相關內容時將再做講解。
3.4 小結
本章內容讓讀者了解了什么是常量和變量,以及它們如何使用,常量最終可以理解為一些程序運行的始末不能改變的量。變量則是那些值可以發生改變的量,主要用于保存計算的中間結果或其他數據。變量的另一個重要的用途是引用各種各樣的對象,通過變量可以操作內存中的對象。
變量的命名有一定的規范,重要的一點是不能與系統保留的關鍵字同名。規范的命名不僅使代碼工整漂亮,而且能降低后期維護工作的難度。下一章將講解另一個重要的內容,表達式與運算符。如果讀者對本章內容還有什么疑問,可以參考《完全手冊:HTML+CSS+JavaScript實用詳解》(電子工業出版社,葉青)和《JavaScript權威指南》(機械工業出版社)等書籍。
3.5 習題
一、常見面試題
1.簡單說明一下JavaScript中常量和變量的定義及區別。
【解析】本題考查的是變量和常量的定義。
【參考答案】常量通常用來表示一些值固定不變的量,比如圓周率、萬有引力等,一般直接使用,不需要使用關鍵字定義,包括字符串型、布爾型、數值型和null等。變量是指在程序運行過程中值可以發生改變的量,更為專業的說法就是指可讀寫的內存單元。一般使用var來定義變量。
2.簡述變量的作用范圍。
【解析】任何語言的變量都是有一定時效性的,不是一直有效,也不是一直存在。本題考核的是對變量作用域的了解。
【參考答案】JavaScript變量的作用域有全局和局部之分。全局作用域的變量在整個程序范圍都有效,局部作用域指作用范圍僅限于變量所在的函數體。
二、簡答題
1.什么是變量?它和常量有什么區別?
2.變量的作用有哪些?JavaScript中變量的類型有哪些?
3.寫出JavaScript中的運算符關鍵字。
三、綜合練習
1.編寫一個程序,將數字13、55、37、33、45、9、60、21、10從小到大排序,并將排序后的各數字輸出。
【提示】定義一個數組變量,將各數字填入數組。遍歷數組,如果第n個元素小于第n-1個,則交換兩者的內容,如此循環操作即可,參考代碼如下:
01 <script language="javascript"> 02 <!-- 03 var oMyArray = new Array( 13, 55, 37, 33, 45, 9, 60, 21, 10 ); // 定義變量引用一個數組對象 04 document.write( "排序前:" + oMyArray ); // 輸出排序前的數組 05 for ( index in oMyArray ) // 開始排序 06 { 07 for ( i in oMyArray ) // 兩兩比較 08 { 09 if( oMyArray[index]<oMyArray[i] ) // 如果當前元素小于第i個元素 10 { 11 nTemp = oMyArray[index]; // 交換位置 12 oMyArray[index] = oMyArray[i]; 13 oMyArray[i] = nTemp; 14 } 15 } 16 } 17 document.write( "<br>排序后:" + oMyArray ); // 輸出排序后的數組 18 --> 19 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖3-7所示。

圖3-7 數組排序
2.實現一個求圓面積的程序,半徑由用戶從外部輸入,計算結果輸出到當前頁面中。
【提示】根據圓面積公式S=π*r2可計算出面積。使用window對象的prompt方法實現半徑的輸入。調用Math對象的PI常作為圓周率π,輸出使用document對象的write方法,參考代碼如下:
01 <script language="javascript"> // 腳本程序開始 02 <!-- 03 var r = prompt( "請輸入圓的半徑:", "0" ); // 用戶輸入圓半徑 04 if( r != null ) // 判斷輸入的合法性 05 { 06 var square = parseFloat( r )*parseFloat( r )*Math.PI; // 計面積 s=π*r*r 07 document.write("半徑為" + parseFloat( r ) + "的圓面積為:" + square ); // 在頁面中輸出結果 08 } 09 else // 輸入不合法 10 { 11 alert("輸入不合法!"); // 輸出提示信息 12 } 13 --> 14 </script> <!--腳本程序結束-->
【運行結果】打開網頁文件運行程序,其結果如圖3-8、圖3-9所示。

圖3-8 輸入圓半徑

圖3-9 輸出圓面積
四、編程題
1.編寫程序比較三個數的大小,并依次輸出。
【提示】可以定義三個變量,然后按照兩兩比較的辦法進行。
2.找出5個數中最大的一個數,并輸出。
【提示】可以定義5個變量,然后將第1個數值與后面的數值進行比較,得出最大者,再用第2個數依次比較,依此類推,最終得到結果。