1. JavaScript 語句
1)if語句
if (condition) statement1 else statement2
這里的條件(condition)可以是任何表達式,并且求值結果不一定是布爾值。
ECMAScript會自動調用Boolean()函數將這個表達式的值轉換為布爾值。
如果條件求值為true,則執行語句statement1;如果條件求值為false,則執行語句statement2。
這里的語句可能是一行代碼,也可能是一個代碼塊(即包含在一對花括號中的多行代碼)。
連續使用多個if語句:
if (condition1) statement1 else if (condition2) statement2 else statement3
2)do-while語句
do-while語句是一種后測試循環語句,即循環體中的代碼執行后才會對退出條件進行求值。
換句話說,循環體內的代碼至少執行一次。
do-while的語法如下:
do {statement
} while (expression);
注意 后測試循環經常用于這種情形:循環體內代碼在退出前至少要執行一次。
3)while語句
while語句是一種先測試循環語句,即先檢測退出條件,再執行循環體內的代碼。
因此,while循環體內的代碼有可能不會執行。
while(expression) statement
4)for語句
for語句也是先測試語句,只不過增加了進入循環之前的初始化代碼,以及循環執行后要執行的表達式。
for (initialization; expression; post-loop-expression) statement
無法通過while循環實現的邏輯,同樣也無法使用for循環實現。因此for循環只是將循環相關的代碼封裝在了一起而已。
在for循環的初始化代碼中,其實是可以不使用變量聲明關鍵字的。不過,初始化定義的迭代器變量在循環執行完成后幾乎不可能再用到了。因此,最清晰的寫法是使用let聲明迭代器變量,這樣就可以將這個變量的作用域限定在循環中。
初始化、條件表達式和循環后表達式都不是必需的。因此,下面這種寫法可以創建一個無窮循環:
for (; ; ) { // 無窮循環doSomething();
}
如果只包含條件表達式,那么for循環實際上就變成了while循環:
let count = 10;
let i = 0;
for (; i < count; ) {console.log(i);i++;
}
5)for-in語句
for-in語句是一種嚴格的迭代語句,用于枚舉對象中的非符號鍵屬性,語法如下:
for (property in expression) statement
ECMAScript中對象的屬性是無序的,因此for-in語句不能保證返回對象屬性的順序。換句話說,所有可枚舉的屬性都會返回一次,但返回的順序可能會因瀏覽器而異。
如果for-in循環要迭代的變量是null或undefined,則不執行循環體。
6)for-of語句
for-of語句是一種嚴格的迭代語句,用于遍歷可迭代對象的元素,語法如下:
for (property of expression) statement
for-of循環會按照可迭代對象的next()方法產生值的順序迭代元素。
如果嘗試迭代的變量不支持迭代,則for-of語句會拋出錯誤。
7)標簽語句
標簽語句用于給語句加標簽,語法如下:
label: statement
下面是一個例子:
start: for (let i = 0; i < count; i++) {console.log(i);
}
在這個例子中,start是一個標簽,可以在后面通過break或continue語句引用。標簽語句的典型應用場景是嵌套循環。
8)break和continue語句
break和continue語句為執行循環代碼提供了更嚴格的控制手段。其中,break語句用于立即退出循環,強制執行循環后的下一條語句。而continue語句也用于立即退出循環,但會再次從循環頂部開始執行。
break和continue都可以與標簽語句一起使用,返回代碼中特定的位置。這通常是在嵌套循環中,如下面的例子所示:
let num = 0;
outermost:
for (let i = 0; i < 10; i++) {for (let j = 0; j < 10; j++) {if (i == 5 && j == 5) {break outermost;}num++;}
}
console.log(num); // 55
9)with語句
with語句的用途是將代碼作用域設置為特定的對象,其語法是:
with (expression) statement;
使用with語句的主要場景是針對一個對象反復操作,這時候將代碼作用域設置為該對象能提供便利,如下面的例子所示:
let qs = location.search.substring(1);
let hostName = location.hostname;
let url = location.href;
上面代碼中的每一行都用到了location對象。如果使用with語句,就可以少寫一些代碼:
with(location) {let qs = search.substring(1);let hostName = hostname;let url = href;
}
這里,with語句用于連接location對象。這意味著在這個語句內部,每個變量首先會被認為是一個局部變量。如果沒有找到該局部變量,則會搜索location對象,看它是否有一個同名的屬性。如果有,則該變量會被求值為location對象的屬性。
嚴格模式不允許使用with語句,否則會拋出錯誤。
警告 由于with語句影響性能且難于調試其中的代碼,通常不推薦在產品代碼中使用with語句。
10)switch語句
switch語句是與if語句緊密相關的一種流控制語句,從其他語言借鑒而來。ECMAScript中switch語句跟C語言中switch語句的語法非常相似,如下所示:
switch (expression) {case value1:statementbreak;case value2:statementbreak;case value3:statementbreak;case value4:statementbreak;default:statement
}
這里的每個case(條件/分支)相當于:“如果表達式等于后面的值,則執行下面的語句。”
break關鍵字會導致代碼執行跳出switch語句。如果沒有break,則代碼會繼續匹配下一個條件。
default關鍵字用于在任何條件都沒有滿足時指定默認執行的語句(相當于else語句)。
為避免不必要的條件判斷,最好給每個條件后面都加上break語句。如果確實需要連續匹配幾個條件,那么推薦寫個注釋表明是故意忽略了break。
雖然switch語句是從其他語言借鑒過來的,但ECMAScript為它賦予了一些獨有的特性。首先,switch語句可以用于所有數據類型(在很多語言中,它只能用于數值),因此可以使用字符串甚至對象。其次,條件的值不需要是常量,也可以是變量或表達式。
switch ("hello world") {case "hello" + " world":console.log("Greeting was found.");break;case "goodbye":console.log("Closing was found.");break;default:console.log("Unexpected message was found.");
}
注意 switch語句在比較每個條件的值時會使用全等操作符,因此不會強制轉換數據類型(比如,字符串"10"不等于數值10)。
2. JavaScript 函數
以下是函數的基本語法:
function functionName(arg0, arg1, ..., argN) {statements
}
可以通過函數名來調用函數,要傳給函數的參數放在括號里(如果有多個參數,則用逗號隔開)。
ECMAScript中的函數不需要指定是否返回值。任何函數在任何時間都可以使用return語句來返回函數的值,用法是后跟要返回的值。
要注意的是,只要碰到return語句,函數就會立即停止執行并退出。因此,return語句后面的代碼不會被執行。
return語句也可以不帶返回值。這時候,函數會立即停止執行并返回undefined。這種用法最常用于提前終止函數執行,并不是為了返回值。
注意 最佳實踐是函數要么返回值,要么不返回值。只在某個條件下返回值的函數會帶來麻煩,尤其是調試時。
嚴格模式對函數也有一些限制:
- 函數不能以eval或arguments作為名稱;
- 函數的參數不能叫eval或arguments;
- 兩個命名參數不能擁有同一個名稱。
如果違反上述規則,則會導致語法錯誤,代碼也不會執行。