1. JavaScript簡介
1.1 JavaScript的誕生
JavaScript誕生於1995年,當時主要目的在處理由服務器端語言負責的一些輸入驗證操作。在JavaScript問世之前,必須把表單數據發送到服務器端才能確定用戶是否輸入了無效值,而當時普遍使用電話拔號上網,速度之慢導致與服務器的一次交互成爲對耐心的考驗,因此Netscape Navigator希望通過JavaScript來解決這個問題。
如今,JavaScript不再侷限於簡單的數據驗證,而是具備了與瀏覽器窗口及內容等幾乎所有方面交互的能力,今天的JavaScript已經成爲一門功能全面的編程語言。
1.2 ECMAScript
一個完整的JavaScript由三個不同的部分組成。
1) 核心(ECMAScript)
2) 文檔對象模型(DOM)
3) 瀏覽器對象模型(BOM)
由ECMA-262定義的ECMAScript與WEB瀏覽器沒有依賴關係,這門語言本身並不包含輸入和輸出定義,我們常見的WEB瀏覽器只是ECMAScript實現可能的宿主環境之一。宿主環境不僅提供基本的ECMAScript實現,同時也會提供該語言的擴展,以便語言與環境之間對接交互。
ECMA-262規定了這門語言的如下組成部分:語法、類型、語句、關鍵字、保留字、操作符、對象。
1.3 文檔對象模型
文檔對象模型(Document Object Model)是針對XML但經過擴展用於HTML的就用程序編程接口,DOM把整個頁面映射爲一個多層節點結構,HTML或XML頁面中的每個組成部分都是某種類型的節點,這些節點又包含着不同類型的數據。
在DOM標準出現一段時間之後,WEB瀏覽器纔開始實現它。IE(IE5-IE8)仍處於實現了DOM1級的狀態,而Chrome 0.2+、Opera 9和Safari 3不僅完全支持DOM1級,還支持DOM2級的大部分。
1.4 瀏覽器對象模型
IE和Netscape都支持可以訪問和操作瀏覽器窗口的瀏覽器對象模型(Browser Object Model)。開發人員使用BOM可以控制瀏覽器顯示的頁面以外的部分。但它作爲JavaScript實現的一部分,至今仍沒有相關的標準。
從根本上說,BOM只處理瀏覽器窗口和框架,但習慣上也把所有針對瀏覽器的JavaScript擴展算作BOM的一部分,例如:
1) 彈出新瀏覽器窗口。
2) 移動、縮放和關閉瀏覽器窗口。
3) 提供瀏覽器詳細信息的navigator對象。
4) 提供用戶顯示器分辨率詳細信息的screen對象。
5) 對cookie的支持。
6) 像XMLHttpRequest和IE的ActiveXObject這樣的自定義對象。
2. 在HTML中使用JavaScript
2.1 Script元素
向HTML中插入JavaScript的主要方法,就是使用<script>元素。HTML 4.01爲<script>定義了5個屬性。
1) charset: 可選的,表示通過src屬性指定的代碼字符集。
2) defer: 可選的,表示腳本可以延遲到文檔完全被解析和顯示之後再執行。
3) language: 已廢棄,用來表示編寫代碼使用的腳本語言。
4) src: 可選的,表示包含要執行代碼的外部文件。
5) type: 必選的,可以看成language的替代屬性,表示編寫代碼使用的腳本語言類型。
2.2 使用Script元素
使用<Script>元素的方式有兩種。
1) 嵌入Javascript
在使用<script>元素嵌入JavaScript代碼時,只須爲<script>指定type屬性,再把JavaScript代碼放在元素內部,例如:
<script type="text/javascript"> function hello() { alert("Hello World!"); } </script>
包含在<script>元素內部的JavaScript代碼將被從上至下依次執行。
2) 包含外部文件
通過<script>元素來包含外部JavaScript文件,需要src屬性,這個屬性的值指向外部JavaScript文件的鏈接,例如:
<script type="text/javascript" src="test.js" ></script>
需要注意的是,帶有src屬性的<script>元素不應該在其<script>和</script>標籤之間再包含額外的JavaScript代碼。
按照慣例,所有<script>元素都應該放在頁面的<head>元素中,但是這意味着必須等到全部JavaScript代碼都被下載、解析和執行完成以後,才能開始呈現頁面的內容。爲了避免這個問題,現代Web應用程序一般都把全部JavaScript引用放在<body>元素中,放在頁面的內容後面。
2.3 文檔模式
IE5.5引入了文檔模式的概念,這個概念是通過使用文檔類型(doctype)切換實現的。最近的兩種文檔模式是混雜模式(quirks mode)和標準模式(standards mode)。混雜模式會讓IE的行爲與IE5相同,而標準模式讓IE更接近標準行爲。此後,IE又提出一種準標準模式(almost standards mode),這種模式下的瀏覽器特性大多符合標準。
如果在文檔開始處沒有發現文檔類型聲明,則所有瀏覽器默認開啓混雜模式,但並不值得推薦,因爲不同瀏覽器在這種模式下的差異非常大。
對於標準模式,可以通過使用下列任一種文檔類型開啓:
<!-- HTML 4.01 嚴格型 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!-- XHTML 1.0 嚴格型 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
對於準標準模式,可以通過下列文檔類型開啓:
<!-- HTML 4.01 過渡型 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!-- HTML 4.01 框架集型 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> <!-- XHTML 1.0 過渡型 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- XHTML 1.0 框架集型 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
2.4 NoScript元素
早期瀏覽器不支持JavaScript,爲了讓不支持的瀏覽器頁面平穩地退化,創造了一個<noscript>元素,用以在不支持JavaScript的瀏覽器中顯示替代的內容。這個元素可以包含能夠出現在文檔<body>中的任何HTML元素,除<script>外。包含在<noscript>元素中的內容只有在以下情況時纔會顯示:
1) 瀏覽器不支持腳本。
2) 瀏覽器支持腳本,但腳本被禁用。
3. 基本語法
3.1 標識符
標識符是可以按照以下格式規則組合起來的一或多個字符:
1) 第一個字符必須是字母、下劃線或美元符號。
2) 其他字符可以是字母、下劃線、美元符號或數字。
ECMAScript中的一切變量、函數名和操作符都區分大小寫。
3.2 註釋
ECMAScript使用C風格的註釋,包括單行註釋和塊級註釋。
1) 單行註釋
// 單行註釋
2) 塊級註釋
/* * 塊級註釋 */
3.3 語句
ECMAScript中的語句以一個分號結尾,如果省略分號,由解析器確定語句的結尾。雖然分號不是必須的,但建議不要省略它,加上分號可以避免很多錯誤。
可以使用C風格的語法把多條語句組合到一個代碼塊中,即以左花括號開頭,以右花括號結尾。
3.4 變量
ECMAScript中的變量是鬆散型的,即可以用來保存任何類型的數據。定義變量時要使用var操作符,後跟變量名,例如:
var myvar;
使用var操作符定義的變量將成爲該變量的作用域中的局部變量,如果在函數中使用var定義一個變量,那麼這個變量在函數退出後就會被銷燬,例如:
function test1() { var myvar1 = "hello"; //局部變量 } function test2() { myvar2 = "hello"; //全局變量 }
可以使用一條語句定義多個變量,只要把每個變量用逗號分隔開即可,例如:
var myvar1 = "hello", myvar2 = 2, myvar3 = true;
4. 數據類型
4.1 數據類型檢測
ECMAScript中有5種簡單數據類型:Undefined、Null、Boolean、Number和String,還有一種複雜數據類型:Object,Object本質上是由一組無序的名值對組成的。
typeof負責提供檢測給定變量數據類型的手段,例如:
var myvar = "Hello World!"; alert(typeof(myvar));
4.2 Undefined
Undefined類型只有一個值,即undefined,在使用var聲明變量但未對其加以初始化時,這個變量的值就是undefined。
包含undefined值的變量與尚未定義的變量的是不一樣的,例如:
var myvar1 = "Hello World!"; alert(myvar1); alert(myvar2); //產生錯誤
但對兩種變量使用typeof操作符都會返回undefined。
4.3 Null
Null類型也只有一個值,即null,從邏輯上看,null值表示一個空對象指針,所以typeof操符符檢測null會返回object。
實際上,undefined值是派生自null的,因此它們的相等性測試返回true。
4.4 Boolean
Boolean類型只有兩個字面值,true和false,注意的是,它們是區分大小寫的,比如True和False都不是Boolean值,只是標識符。
數據類型 | 轉換爲true的值 | 轉換爲false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | 空字符串 |
Number | 任何非零數字值 | 0和NaN |
Object | 任何對像 | null |
Undefined | N/A | undefined |
4.5 Number
Number類型使用IEEE754格式來表示整數和浮點數值。最基本的數值字面量格式是十進制數,此外,還可以通過八進制或十六進制的字面制來表示。其中,八進制字面值的第一位必須是0,十六進制字面值的前兩位必須是0x,例如:
var intNum = 1; var octalNum = 01; var hexNum = 0xA;
NaN,即非數值,是一個特殊的數值,這個數值用於表示一個本來要返回數值的操作數未返回的情況。任何涉及NaN的操作都會返回NaN,且NaN與任何值都不相等,包括NaN本身。
ECMAScript定義了isNaN()函數,這個函數接受一個參數,幫我們確定這個參數是否“不是數值”。isNaN()在接收到參數後,會嘗試將這個值轉換爲數值,任何不能轉換爲數值的值都會導致這個函數返回true,例如:
alert(isNaN("10")); //false alert(isNaN("blue")); //true
有3個函數可以把非數值轉換爲數值:Number()、parseInt()、parseFloat()。Number()可以用於任何類型,而parseInt()和parseFloat()用於字符串。
4.6 String
String類型用來表示零或多個字符序列,即字符串。字符串可以由雙引號或單引號表示,例如:
var myvar1 = "Hello Word!"; var myvar2 = 'Hello Word!';
與PHP不同,ECMAScript中的這兩種語法形式沒有什麼區別。
把一個值轉換成字符串有兩種方式。第一種是使用幾乎每個值都有的toString()方法(null和undefined值沒有這個方法),第二種是使用轉型函數String(),這個函數能將任何類型的值轉換爲字符串,例如:
var myvar1 = 1; var mystr1 = myvar.toString(); var myvar2 = null; var mystr2 = String(myvar2);
4.7 Object
ECMAScript中的對象其實就是一組數據和功能的集合。對象可以通過執行new操作符來創建,而創建Object類型的實例併爲其添加屬性和方法,就可以創建自定義對象,例如:
var myobj = new Object();
Object實例具有下列屬性和方法:
1) constructor: 保存用於創建當前對象的函數。
2) hasOwnProperty(propertyName): 用於檢查給定的屬性在當前對象實例中是否存在。
3) isPrototypeOf(object): 用於檢查傳入的對象是否是另一個對象的原型。
4) propertyIsEnumerable(propertyName): 用於檢查給定的屬性是否能夠使用for-in語句來枚舉。
5) toString(): 返回對象的字符串表示。
6) valueOf(): 返回對象的字符串、數值或布爾值表示。
5. 操作符
5.1 一元操作符
只能操作一個值的操作符叫做一元操作符。一元操作符是ECMAScript中最簡單的操作符。
操作符 | 名稱 | 示例 |
---|---|---|
++ | 遞增 | ++a |
-- | 遞減 | --a |
+ | 一元加 | +a |
- | 一元減 | -a |
5.2 位操作符
位操作符用於在最基本的層次上,即按內存中表示數值的位來操作數值。ECMAScript中的所有數值都以IEEE 64位格式存儲,但位操作符並不直接操作64位的值,而是先將64位的值轉換爲32位的整數,然後執行操作,最後再將結果轉換回64位。
操作符 | 名稱 | 示例 |
---|---|---|
~ | 按位非 | ~a |
& | 按位與 | a & b |
| | 按位或 | a | b |
^ | 按位異或 | a ^ b |
<< | 左移 | a << 2 |
>> | 有符號右移 | a >> 2 |
>>> | 無符號右移 | a >>>2 |
5.3 布爾操作符
布爾操作符一共有3個:非、與、或。
操作符 | 名稱 | 示例 |
---|---|---|
! | 邏輯非 | !a |
&& | 邏輯與 | a && b |
|| | 邏輯或 | a || b |
5.4 乘性與加性操作符
ECMAScript定義了3個乘性操作符與2個加性操作符。
操作符 | 名稱 | 示例 |
---|---|---|
* | 乘法 | a * b |
/ | 除法 | a / b |
% | 求模 | a % b |
+ | 加法 | a + b |
- | 減法 | a - b |
5.5 關係操作符
關係操作符用於對兩個值進行比較,比較規則與數學規則一致。關係操作符都將返回一個布爾值。
操作符 | 名稱 | 示例 |
---|---|---|
< | 小於 | a < b |
> | 大於 | a > b |
<= | 小等於 | a<= b |
>= | 大等於 | a >= b |
5.6 其他操作符
1) 條件操作符
條件操作符格式如下所示:
variable = boolean_expression ? true_value : false_value
2) 賦值操作符
簡單的賦值操作符由等號(=)表示,其作用就是把右側的值賦給左側的變量。如果在等號前再添加乘性操作符、加性操作符或位操作符,就可以完成複合賦值操作,例如:
var myvar = 10; myvar += 10;
3) 逗號操作符
使用逗號操作符可以在一條語句中執行多個操作,例如:
var myvar1 = 1, myvar2 = 2, myvar3 = 3;
除此之外,逗號操作符還可以用於賦值,在用於賦值時,逗號操作符總會返回表達式中的最後一項,例如:
var myvar = (1, 2, 3, 4, 5);
6. 條件語句
6.1 if else語句
if (condition) { statement; } else { statement; }
大多數編程語言中最爲常用的就是if語句,其中的condition可以是任意表達式,ECMAScript會自動調用Boolean()轉換函數將這個表達式的結果轉換爲一個布爾值。
6.2 do while語句
do { statement; } while(expression);
do while語句是一種後測試循環語句,只有在循環體中的代碼執行之後,纔會測試條件,即對條件表達式求值之前,循環體中的代碼至少會被執行一次。
6.3 while語句
while (expression) { statement; }
while語句屬於前測試循環語句,即在循環體內的代碼被執行之前,就會對條件求值。
6.4 for語句
for (initialization; expression; post-loop-expression) { statement; }
for語句也是一種前測試循環語句,但它具有在執行循環前初始化變量和定義循環後要執行的代碼的能力。
6.5 for-in語句
for (property in expression) { statement; }
for in語句是一種精準的迭代語句,可以用來枚舉對象的屬性。ECMAScript對象的屬性沒有順序,因此,通過for in語句輸出的屬性名的順序是不可預測的。
6.6 label語句
label: statement
使用label標籤可以在將來由break或continue語句引用。break和continue語句用於在循環中精確地控制代碼執行。其中,break語句會立即退出循環,強制繼續執行循環後面的語句。而continue語句雖然也是立即退出循環,但退出循環後會從循環的頂部繼續執行。
6.7 with語句
with (expression) { statement; }
with語句的作用是將代碼的作用域設置到一個特定的對象中。with語句的代碼塊內部,每個變量首先被認爲是一個局部變量,而如果在局部環境中找不到該變量的定義,就會查詢表達式的作用域。
6.8 swtich語句
swtich (expression) { case value1: expression; break; case value2: expression; break; case value3: expression; break; defalut: statement; }
switch語句中當表達式的值等於一種情形(case),則執行後面的語句,直至遇到break或swtich語句結束。最後的default關鍵字則用於在表達式不匹配前面任何一種情形的時候,執行機動代碼。
7. 函數
函數對任何語言都是一個核心的概念,通過函數可以封裝任意多條語句,而且可以在任何時候,任何地方調用執行。ECMAScript中的函數使用function關鍵字來表明,後跟一組參數以及函數體。基本語法如下:
function functionName(arg0, arg1, ..., argN) { statement; }
ECMAScript中的函數在定義時不必指定是否返回值,或在任何時候都可以通過return語句返回值。
ECMAScript中的參數與大多數語言不同,它不介意傳遞進來的參數個數和數據類型,原因是ECMAScript中的參數在內部是用一個數組來表示的,函數接收到的始終都是這個數組,而不關心數組中包含哪些參數。
ECMAScript函數不能像傳統意義上實現重載,如果定義了兩個名字相同的函數,那麼該名字只屬於後定義的函數。