[TOC]
流程控制語句一般用來判斷分支或者重復執行某段代碼時使用。
## if條件分支語句
if語句是流程控制語句中最常用的一種分支語句,可以根據不同的條件,執行不同分支的代碼,其格式為:
~~~
if (condition) {statement1} else {statement2}
~~~
其中 `condition` 可以是任意表達式,也可以是其它類型數據,執行時會自動調用`Boolean()`函數將其轉換為布爾值,如果為 `true`,則執行接下來的`statement1`代碼塊,如果為 `false`,則執行 `else`中的`statement2`代碼塊,如果代碼塊中,只有一句代碼,可以省略花括號`{}`,但在實際應用中,不推薦省略。
~~~
var i = 20;
// 推薦寫法
if( i < 30 ) {
alert("20 小于 30");
} else {
alert("20 大于 30");
}
// 不推薦寫法
if ( i < 30 ) alert("20 小于 30");
else alert("20 大于 30");
~~~
如果,我們需要進行多種值的判斷,讓執行不同的代碼,那么,可以使用以下語法
~~~
if (i > 25) {
alert("Greater than 25.");
} else if (i < 0) {
alert("Less than 0.");
} else {
alert("Between 0 and 25, inclusive.");
}
~~~
以上表示,如果 `i` 大于`25`,則弱出`Greater than 25.`,否則,會執繼續判斷`i`是否小于`0`,如果成立,則彈出`Less than 0.`,如果以上都不成立,則會執行`else`中的代碼塊。需要注意的是,其中的 `else if` 可以使用多次。
## do-while循環語句
語法:
~~~
do {
statement
} while (expression);
~~~
do-while 語句,先會執行`do`循環中的代碼塊,然后再判斷`while`中的條件,如果條件符合,繼續執行`do`循環中的代碼塊,直到`while`中的條件不成立,才會中斷循環的執行。也就是說,無論`while`中的條件是否成立,`do`循環中的代碼塊至少會被執行一次。
~~~
var i = 0;
do {
alert(i);
i++;
} while ( i < 10 );
~~~
## while循環語句
while循環語句會先判斷條件,如果條件滿足再執行循環體中的代碼,如果不成立,則不會執行。
~~~
語法:
while (expression) {statement}
示例:
var i =1;
while ( i < 10 ) {
alert(i);
i++;
}
~~~
在實際應用中,`while`語句使用較少,一般會用` for` 循環語句代替。
## for循環語句
`for`循環可能是循環語句中使用最頻繁的語句了,一般用來重復執行某段代碼塊指定次數,語法如下:
~~~
for (initialization; expression; post-loop-expression) { statement }
~~~
在`for`循環中,小括號中有三個語句,每個語句之間用分號(;)隔開,其中第一個語句`initialization`是用來定義初始變量的,是在循環之前就會執行,并且只執行這一次;第二個語句`expression`是表示循環條件,達到此條件,就執行循環,如果不滿足此條件,則終止執行該循環;第三個語句`post-loop-expression`一般是在循環迭代使用,此語句是在當前循環執行完畢后再執行。
~~~
for (var i = 0; i < 3; i++) {
alert( i );
}
~~~
上面這個示例將會連續彈出三個警告框,內容分別是:0、1、2。執行順序為:
* 第一次循環: 首先 `for` 循環中的第一個語句會被無條件執行,所以,會定義一個變量 `i`,值為`0`,然后判斷條件,`i < 3`,此時 i 的值為` 0`,所以滿足條件,則執行循環體,彈出變量 `i` ,也就是 `0`,然后再執行for循環中的第三個語句 `i++`;
* 第二次循環:因為不是第一次循環了,所以`for`循環小括號中的第一個語句就不會被執行了,直接判斷條件 `i < 3`,此時的`i`在上一次循環已經被執行了` i++` 的遞增操作,所以值為 `1`, `1 < 3` 條件成立,所以繼續執行循環體,彈出變量`i`的值 `1`,然后再執行了`for`循環中的第三個語句`i++`;
* 第三次循環:和第二次一樣,不再執行` for` 循環小括號中的第一個語句,直接判斷條件,此時 i的值經過第二次循環中的遞增操作后為`2`,`2 < 3` 的條件成立,則繼續執行循環體,彈出變量`i`的值,也就是`2`,然后執行`for`循環小括號中的第三個語句` i++`;
* 第四次循環:也是直接判斷條件,此時的 `i` 經過第三次循環的遞增操作,已經為 `3` 了,`i < 3 ` 條件不成立,所以就終止了當前的`for`循環的執行,到這里整個循環結束。
## for-in 循環語句
for-in 語句是一種精準的迭代語句,可以用來枚舉對象的屬性。以下是 for-in 語句的語法:
~~~
for (property in expression) { statement }
~~~
下面是一個示例:
~~~
//數組實例
var arr = ['red','blue','yellow','green'];
for (var x in arr) {
document.write(arr[x] + '<br />');
}
//輸出
red
blue
yellow
green
~~~
~~~
//對象實例
var obj = {"name":"howie","age":25,"email":"xjdnw@sina.com"};
for (var x in obj) {
document.write(x + '<br />');
}
//輸出
name
age
email
var obj = {"name":"howie","age":25,"email":"xjdnw@sina.com"};
for (var x in obj) {
document.write(obj[x] + '<br />');
}
// 輸出
// howie
// 25
// xjdnw@sina.com
~~~
>[danger] 如果表示要迭代的對象的變量值為 null 或 undefined , for-in 語句會拋出錯誤。ECMAScript 5 更正了這一行為;對這種情況不再拋出錯誤,而只是不執行循環體。為了保證最大限度的兼容性,建議在使用 for-in 循環之前,先檢測確認該對象的值不是 null 或 undefined 。
## for...of 循環
for...of 循環一般用于循環數組,與for...in不同的是,for...of每次循環出來的是數組元素本身,而不是索引,例如還是上面的數組,用for...of,就會簡單很多:
~~~
//數組實例
var arr = ['red','blue','yellow','green'];
for (var x in arr) {
document.write(x + '<br />');
}
// 輸出
// red
// blue
// yellow
// green
~~~
## label語句
使用 label 語句可以在代碼中添加標簽,以便將來使用。以下是 label 語句的語法:
~~~
label: statement
~~~
其中的`label`可以任何不是保留關鍵字的 JavaScript 標識符,`label`語句可使用一個標簽來唯一標記一個循環,然后使用`break`或`continue`語句來指示程序是否中斷循環或繼續執行。例如:
~~~
var count = 5;
start: for (var i = 0; i < count; i++) {
console.log(i);
}
//結果
// 0
// 1
// 2
// 3
// 4
// 5
~~~
## break 和 continue 語句
`break` 和 `continue`都是終止循環語句,區別是`break`語句是立即終止執行,而`continue`則是終止本次循環,繼續下一次循環。
~~~
for (var i = 0; i <= 5; i++) {
if (i == 3) {
break;
}
console.log(i);
}
// 結果輸出
// 0
// 1
// 2
~~~
由此可見,當執行到`break`時,直接終止了當前的循環,不再繼續執行循環中的任何代碼而下面的例子則是`continue`的執行情況。
~~~
for (var i = 0; i <= 5; i++) {
if (i == 3) {
continue;
}
console.log(i);
}
// 輸出結果
// 0
// 1
// 2
// 4
// 5
~~~
由此可見,當執行到`continue`的時候,只是終止了當前循,而繼續執行下一次循環。
## with 語句
`with`語句用于設置代碼在特定對象中的作用域,語法如下:
~~~
with (expression) statement
~~~
定義 with 語句的目的主要是為了簡化多次編寫同一個對象的工作,如下面的例子所示:
~~~
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
~~~
上面幾行代碼都包含 location 對象。如果使用 with 語句,可以把上面的代碼改寫成如下所示:
~~~
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
~~~
>[danger] 由于大量使用 with 語句會導致性能下降,同時也會給調試代碼造成困難,因此在開發大型應用程序時,不建議使用 with 語句。
## switch 語句
witch 語句是 if 語句的兄弟語句,在實際開發過程中,使用非常頻繁。我們可以用 switch 語句為表達式提供一系列的情況`(case)`。`switch` 語句的語法如下:
~~~
switch (expression) {
case value: statement;
break;
case value: statement;
break;
case value: statement;
break;
case value: statement;
break;
...
case value: statement;
break;
default: statement;
}
~~~
`switch`語句中的每一種情形(`case`)表示:如果表達式(`expression`)的值等于這個值(`value`),則執行后面的代碼塊(`statement`)。而 `break`關鍵字代表跳出當前`switch`語句,`break`一般情況不應該被省略,因為如果代碼執行沒遇到`break`關鍵字,會繼續執行下一個`case`,而最后的`default`關鍵字則表示,上面的所有`case`的`value`都不匹配表達式`expression`的時候,默認會執行`default`中的代碼塊。`switch`語句的出現是為了解決下面這種重復`if...elseif...`的問題。
~~~
if (i == 25){
alert("25");
} else if (i == 35) {
alert("35");
} else if (i == 45) {
alert("45");
} else {
alert("Other");
}
~~~
以上這段代碼可以用`switch`語句表示如下:
~~~
switch (i) {
case 25:
alert("25");
break;
case 35:
alert("35");
break;
case 45:
alert("45");
break;
default:
alert("Other");
}
~~~
而case中,可以合并多種值的情況,例如上面這個例子中,我們希望 `i`等于`25`和`35`的時候,都執行相同代碼時,可以用如下書寫方式:
~~~
switch (i) {
case 25:
case 35:
alert("35 or 35");
break;
case 45:
alert("45");
break;
default:
alert("Other");
}
~~~
在`switch`的`case`中,我們也可以使用表達式,如:
~~~
var num = 25;
switch (true) {
case num < 0:
alert("Less than 0.");
break;
case num >= 0 && num <= 10:
alert("Between 0 and 10.");
break;
case num > 10 && num <= 20:
alert("Between 10 and 20.");
break;
default:
alert("More than 20.");
}
~~~
>[danger] 能使用`switch`語句代替 `if...elseif`的,盡量使用`switch`語句,`switch`語句的運行效率要高于 `if...elseif...`