[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...`