循环语句使得我们可以很方便地重复执行一段代码一定次数。JavaScript提供了非常多的循环机制, 不同的循环机制提供了进入或退出循环的不同的方式,不同的循环机制往往在某些场景下用起来比 其他方式更加高效。
JavaScript中与循环有关的语句有:
for
语句do...while
语句while
语句- 标签语句(labeled statement)
break
语句continue
语句for...in
语句for...of
语句
JavaScript中的for
语句与Java以及C/C++的for
语句非常类似。如下所示是for
语句的语法:
for ([initialExpression]; [condition]; [incrementExpression]) {
statements;
}
其中方括号表面语句可以缺省。for
语句退出的条件是condition
判定为false
时退出,否则
一直循环执行for
语句体中的statements
。以下是一个简单的例子:
for (let i = 0; i < 3; i++) {
console.log(i);
}
/* 输出
0
1
2
*/
执行for
语句时,首先会初始化变量i
,然后执行语句体console.log(i)
,因此首次执行时
输出的值为0
,然后会执行incrementExpression
,i
自增,其值变为1
,然后进行判定i
是否小于3
,若小于3
,则继续执行语句体中的语句,若不小于3
,则循环退出。
do...while
语句会一直循环,直到特定的条件语句判定为false
。do...while
语句如下所示:
do {
statements;
} while (condition);
进入do...while
循环时,先执行statements
,然后进行condition
判定,若判定为true
,
则继续执行statements
,若为false
,则跳出循环,接着执行do...while
语句之后的语句。
以下是一个例子:
var i = 0;
do {
i++;
console.log(i);
} while (i < 3);
/*输出
1
2
3
*/
只要其condition
语句被判定为true
,while
语句会一直对其语句块中的语句循环执行,直到condition
被判定为false
,
然后再接着执行while
语句之后的语句。while
循环如下所示:
while (condition) {
statements;
}
以一个例子说明:
var n = 0;
var x = 0;
while (n < 3) {
n++;
x += n;
}
console.log(x);
/*输出 (x = 1 + 2 + 3)
6
*/
使用循环的时候,要注意防止出现死循环,也就是condition
会一直判定为true
,循环永远也不能执行完毕。
label
可以使得我们为一条语句设置一个名称,从而可以在程序的其他地方来引用被label的语句。比如你可以用label
来标示一个循环语句,然后与break
语句或者continue
语句配合来实现对特定循环的中断或者继续执行。labe
语句的形式
如下:
label:
statement
label
可以是任何符合JavaScript命名规则的标识符(保留字除外)。你可以用label
标识任何语句。例如:
markLoop:
while (theMark == true) {
doSomething();
}
break
语句可以用来中断一个循环的执行、或者switch
语句的执行。在JavaScript中,其还可以与label
语句配合使用。
- 当
break
不与label
进行配合,break
将中断包含其自身的最里层的循环或switch
,然后执行紧接着循环或switch
的语句。 - 当与
label
配合使用,break
将中断被label
标识的语句。
break
语句的格式如下:
break [label];
例如:
for (let i = 0; i < a.length; i++) {
if (a[i] == theValue) {
break; //break一旦执行,将中断该for语句的执行
}
}
又例如:
var x = 0;
var z = 0;
labelCancelLoops: while (true) {
console.log('Outer loops: ' + x);
x += 1;
z = 1;
while (true) {
console.log('Inner loops: ' + z);
z += 1;
if (z === 10 && x === 10) {
break labelCancelLoops; //如果此语句执行,将直接中断最外层while循环
} else if (z === 10) {
break; //如果此语句执行,将中断内层whil循环
}
}
}
continue
语句可以用来重启一个while
,do-while
,for
或者label
语句
-
当
continue
单独使用是,continue
作用的是最里层离continue
语句最近的循环。continue
语句将 使得循环体中在其之后的语句得不到执行而直接开始另一个迭代。continue
与break
不同,其不中止循环的执行 而只是跳过后面的语句继续执行,在while
循环中,会跳回到循环条件判定,而在for
循环中,会跳到incrementExpression
。 -
当与
label
共用时,continue
作用的循环是由label
标识的循环。
例如:
var i = 0;
var n = 0;
while (i < 5) {
i++;
if (i == 3) {
continue;
}
n += i; // n = 1 + 2 + 4 +5 = 12
}
console.log(n); // => 12
又例如:
var i = 0;
var j = 8;
checkiandj:
while (i < 4) {
console.log('i is ' + i);
i += 1;
checkj:
while (j > 4) {
console.log(j);
j -= 1;
if ((j % 2) == 0) {
continue checkj; //如果该语句执行,将跳过checkj循环体后面的语句,执行下一轮checkj循环
//continue checkiandj; //如果该语句执行,将跳过checkiandj循环体后面的语句。执行下一轮checkiandj循环
}
console.log(j + ' is odd.');
}
console.log('i = ' + i);
console.log('j = ' + j);
}
for...in
循环会遍历一个对象的所有可枚举的属性名称。其语句形式如下所示:
for (variable in object) {
statements
}
例子:
function dump_props(obj, obj_name) {
var result = '';
for (var i in obj) {
result += obj_name + '.' + i + ' = ' + obj[i] + '\n';
}
return result;
}
var car = {
make: 'Ford',
model: 'Mustang'
}
var result = dump_props(car, 'car');
console.log(result);
/* 输出
car.make = Ford
car.model = Mustang
*/
提醒:虽然看起来可以用for...in
来迭代Array
,但是它除了反馈数字索引外还有
可能返回你自定义的属性名称。因此还是使用传统的for
循环来迭代Array
要好。
var arr = [1, -1, 2, 6];
for (var i in arr) {
console.log(i, arr[i]);
}
arr.name = 'number_array';
console.log('After add a custom property')
for (var i in arr) {
console.log(i, arr[i]);
}
/* 输出
0 1
1 -1
2 2
3 6
After add a custom property
0 1
1 -1
2 2
3 6
name number_array
*/
由上例所示,当在Array
中加入自定义的属性时,用for...in
语句也是可以访问到那个属性的,
这在大多数情况下会产生意料之外的结果。
提醒:该特性属于ECMAScript 2015(ES6)规范
for...of
将会对可迭代对象(包括Array
,Map
,Set
,arguments
等等)的每一个属性值进行
遍历。其语句形式为:
for (variable of object) {
statement
}
接下来的例子将显示for...of
语句和for...in
语句的区别。for...in
语句遍历的是属性名称,而
for...of
遍历的是属性值。
let arr = [3, 5, 7];
arr.foo = 'hello';
for (let i in arr) {
console.log(i); // => 0 1 2 foo
}
for (let i of arr) {
console.log(i); // => 3 5 7
}
//当对一个对象进行遍历时,会报错
var car = {
make: 'Ford',
model: 'Mustang'
}
for (let i of car) {
console.log(i);
}
// Uncaught TypeError: undefined is not a function
Reference
[1] JavaScript Guide: Loops and iteration