Jscript 腳本中的語句一般是按照寫的順序來運行的。這種運行稱為順序運行,是程序流的默認方向。
與順序運行不同,另一種運行將程序流轉換到腳本的另外的部分。也就是,不按順序運行下一條語句,而是運行另外的語句。
要使腳本可用,該控制的轉換必須以邏輯方式執(zhí)行。程序控制的轉換是基于一個“決定”,這個“決定”結果是真或假(返回 Boolean 型 true 或 false)。創(chuàng)建一個表達式,然后測試其是否為真。主要有兩種程序結構實現(xiàn)本功能。
第一種是選擇結構。用來指明兩種程序流方向,在程序中創(chuàng)建一個交叉點(像岔路)。在 Jscript 中有四種選擇結構可用。
第二種類型的程序控制結構是循環(huán)結構。使用循環(huán)結構來指明當某些條件保持為真時要重復的動作。當控制語句的條件得到滿足時(通常在某些迭代的特定數(shù)字后),控制跳過循環(huán)結構傳遞到下條語句。在 Jscript 中有四種循環(huán)結構可用。
通過嵌套和堆棧選擇、循環(huán)控制結構,可以創(chuàng)建相當復雜的腳本。
第三種形式的結構程序流由意外處理給出,本文檔不作討論。
JScript 支持 if 和 if...else 條件語句。在 if 語句中將測試一個條件,如果該條件滿足測試,執(zhí)行相關的 JScript 編碼。在 if...else 語句中,如果條件不滿足測試,則將執(zhí)行不同的代碼。最簡單的 if 語句格式可以在一行中寫完,不過更常見的是多行的 if 和 if...else 語句。
下述示例演示了使用 if 和 if...else 語句的各種可能的語法。第一個示例演示了最簡單的布爾測試。當(且僅當)括號之間的項的值為(或者可被強制轉換為) true 時,if 后續(xù)的語句或語句塊才會被執(zhí)行。
// smash() 函數(shù)是在該代碼的其他地方定義的。 // 布爾測試,看 newShip 是否為 true。 if (newShip) smash(champagneBottle,bow); // 在本示例中,除非兩個條件都為真,否則該測試將不會被滿足。 if (rind.color == "deep yellow " && rind.texture == "large and small wrinkles") { theResponse = ("Is it a Crenshaw melon?"); } // 在本示例中,只要任何一個條件為真,則測試即會滿足。 var theReaction = ""; if ((dayOfWeek == "Saturday") || (dayOfWeek == "Sunday")) { theReaction = ("I'm off to the beach!"); } else { theReaction = ("Hi ho, hi ho, it's off to work I go!"); }
JScript 也支持隱式的條件格式。該格式在要測試的條件后使用一個問號(而不是在條件前的 if )。它也指定兩個可選項,一個在滿足條件時使用,另一個在條件不滿足時使用。這兩個選擇項之間必須用一個冒號隔開。
var hours = ""; // 下面的代碼指定 hours 是包含 theHour 的內容, // 還是包含 theHour - 12 的內容。 hours += (theHour >= 12) ? " PM" : " AM";
如果要一起測試多個條件,并且知道某個條件比其他條件更可能滿足或不滿足測試,可以使用稱為“短路計算”的特性來加速腳本的運行速度。當 JScript 計算邏輯表達式時,只計算要得到結果所需的子表達式。
例如,如果有一個“與”表達式,如 ((x == 123) && (y == 42)),Jscript 首先檢查 x 是否為 123。如果不是,即使 y 等于 42,整個表達式的值也不可能為 true。因此,并不對 y 作測試,Jscript 返回 false 值。
類似地,如果多個條件中只要有一個為真(使用 || 運算符),則當任何一個條件滿足該測試時測試則停止。如果要測試的條件包括函數(shù)調用或其他復合表達式,這種處理方式就有效。出于此種想法,寫 OR 表達式時,先寫最有可能為 true 的條件。寫 AND 表達式時,先寫最有可能為 false 的條件。
以這種方式設計腳本的好處是:在下例中如果 runfirst() 返回 0 或 false, 則不會運行 runsecond()。
if ((runfirst() == 0) || (runsecond() == 0)) { // 若干代碼。 }
有多種方式來重復執(zhí)行一條語句或語句塊。通常重復執(zhí)行被稱為循環(huán)或重復。重復只是循環(huán)的一個運行。典型情況是用一個變量測試來進行控制,每執(zhí)行一次循環(huán)變量的取值都會更改。JScript 支持四種循環(huán):for 循環(huán)、for...in 循環(huán)、while 循環(huán)、do...while循環(huán)。
for 語句指定了一個計數(shù)器變量,一個測試條件,以及更新該計數(shù)器的操作。在每次循環(huán)的重復之前,都將測試該條件。如果測試成功,將運行循環(huán)中的代碼。如果測試不成功,不運循環(huán)中的代碼,程序繼續(xù)運行緊跟在循環(huán)后的第一行代碼。在執(zhí)行該循環(huán)后,計算機變量將在下一次循環(huán)之前被更新。
如果循環(huán)條件永不會滿足,則不執(zhí)行該循環(huán)。如果測試條件始終滿足,則將導致無限循環(huán)。在有些情況下,前者可能是合乎需要的,而后者幾乎沒有用處,因此在編寫循環(huán)條件時一定要注意。
/* 更新表達式 (下例中的 "icount++")將在循環(huán)結束時被執(zhí)行, 即在構成循環(huán)主體的語句塊被執(zhí)行后, 在測試條件之前。 */ var howFar = 10; // 將循環(huán)次數(shù)限制為 10。 var sum = new Array(howFar); // 創(chuàng)建一個稱為 sum 并具有 10 個成員的數(shù)組,這 10 個成員從 0 到 9。 var theSum = 0; sum[0] = 0; for(var icount = 0; icount < howFar; icount++) { // 在本例中將從 0 到 9 進行計數(shù)。 theSum += icount; sum[icount] = theSum; } var newSum = 0; for(var icount = 0; icount > howFar; icount++) { // 該循環(huán)根本不會被執(zhí)行,因為 icount 不大于 howFar。 newSum += icount; } var sum = 0; for(var icount = 0; icount >= 0; icount++) { // 這是一個無限循環(huán)。 sum += icount; }
JScript 提供了一種特別的循環(huán)方式來遍歷一個對象的所有用戶定義的屬性或者一個數(shù)組的所有元素。for...in 循環(huán)中的循環(huán)計數(shù)器是一個字符串,而不是數(shù)字。它包含當前屬性的名稱或者當前數(shù)組元素的下標。
下面的代碼范例應在 Internet 瀏覽器中運行,因為它使用 alert 方法,該方法不屬于 Jscript。
// 創(chuàng)建具有某些屬性的對象 var myObject = new Object(); myObject.name = "James"; myObject.age = "22"; myObject.phone = "555 1234"; // 枚舉(循環(huán))對象的所有屬性 for (prop in myObject) { // 顯示 "The property 'name' is James",等等。 window.alert("The property '" + prop + "' is " + myObject[prop]); }
盡管 for...in 循環(huán)看起來像 VBScript 的 For Each...Next 循環(huán),其實并不一樣。JScript 的 for...in 循環(huán)重復Jscript 對象所有的屬性。VBScript 的 For Each...Next 循環(huán)重復集合中的所有項目。要循環(huán) JScript 中的所有集合,需要用 Enumerator 對象。盡管某些對象(像 Internet 瀏覽器中的那些)支持 VBScript 的 For Each...Next 和 Jscript 的 for...in 循環(huán),但多數(shù)對象并不都支持。
while 循環(huán)相似于 for 循環(huán)。其不同之處是 while 循環(huán)沒有內置的計數(shù)器或更新表達式。如果希望控制語句或語句塊的循環(huán)執(zhí)行,需要不只是“運行該代碼 n 次”,而是更復雜的規(guī)則,用 while 循環(huán)。下面的示例使用 Internet 瀏覽器對象模型和 while 循環(huán)來詢問用戶一個簡單的問題。
var x = 0; while ((x != 42) && (x != null)) { x = window.prompt("What is my favourite number?", x); } if (x == null) window.alert("You gave up!"); else window.alert("Yep - it's the Ultimate Answer!");
注意 由于 while 循環(huán)沒有顯式的內置計數(shù)器變量,因此比其他類型的循環(huán)更容易產生無限循環(huán)。此外,由于不易發(fā)現(xiàn)循環(huán)條件是在何時何地被更新的,很容易編寫一個實際上從不更新條件的 while 循環(huán)。因此在編寫 while 循環(huán)時應特別小心。
同上面所提到的,在 JScript 中還有 do...while 循環(huán)與 while 循環(huán)相似,不同處在于它總是至少運行一次,因為是在循環(huán)的末尾檢查條件,而不是在開頭。例如,上面的循環(huán)可以被改寫為:
var x = 0; do { x = window.prompt("What is my favourite number?", x); } while ((x != 42) && (x != null)); if (x == null) window.alert("You gave up!"); else window.alert("Yep - it's the Ultimate Answer!");
在 Microsoft Jscript 中當某些條件得到滿足時,用 break 語句來中斷一個循環(huán)的運行。(請注意,也用 break 語句退出一個 switch 塊。)。如果是一個 for 或者 for...in 循環(huán),在更新計數(shù)器變量時使用 continue 語句越過余下的代碼塊而直接跳到下一個循環(huán)中。
下面的例子基于前面的示例用 break 和 continue 語句控制循環(huán)。
var x = 0; do { x = window.prompt("What is my favourite number?", x); // 判斷用戶是否選擇取消?如果是,退出循環(huán)。 if (x == null) break; // 是否輸入一個數(shù)? // 如果是則無需要求輸入一個數(shù)。 if (Number(x) == x) continue; // 要求用戶只輸入數(shù)字。 window.alert("Please only enter in numbers!"); } while (x != 42) if (x == null) window.alert("You gave up!"); else window.alert("Yep - it's the Ultimate Answer!");