for
语句
基本语法
for
循环是大家非常熟悉的也经常用的一种写法,一个for
语句的基本语法为
// 括号中的三个条件都可省略
for ([initialExpression]; [condition]; [incrementExpression])
statement
当condition
为true时,执行顺序:
initialExpression
->condition
->statement
->incrementExpression
initialExpression
初始化表达式,可以是一个任意复杂度的表达式,也可以声明变量。
// 常见用法1
for(let i = 0; i < 3; i++) { ... }
// 常见用法2
for(let i = 0, j = 3; i < j; i++) { ... }
condition
执行for
循环的条件表达式,如果值为true,循环中的语句会被执行,如果值为false,for
循环终止。如果condition
语句被省略,默认为true。
// condition默认为true,所以下面语句会进入死循环
for(;;) { ... }
statement
for
循环的执行体。
incrementExpression
更新表达式,一般用于更新循环变量,使得若干次循环后不满足条件而退出循环。
实例
for(let i = 0, j = 3; i < j; i++) {
console.log(i);
}
while
语句
基本语法
while (condition)
statement
当condition
为true时,则执行statement
,然后继续检查condition
,如果为false,则跳出循环执行后面的语句,所以如果当condition
一直为true时,则会进入死循环。
// 下面语句会进入死循环
while (true) {
console.log('loop');
}
实例
let i = 0
while (i < 10) {
i++;
console.log(i)
}
do ... while
语句
基本语法
do
statement
while (condition);
与while
语句不同的是,不管条件如何,会首先执行一遍statement
,然后再进行condition
条件判断,如果为true则继续执行statement
,如果为false则跳出循环执行后面的语句。
实例
let i = 0
do {
i++;
console.log(i)
} while (i < 10)
for ... in
语句
基本语法
for ... in
语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性
for (variable in object) {
statements
}
请注意:循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性。
实例
function parent(){
this.x = 1;
this.y = 2
}
parent.prototype = {
a: 'a',
b: 'b'
}
const child = new parent()
for(let key in child) {
console.log(key)
}
// 输出
// x
// y
// a
// b
可以看到原型上的a,b属性也被遍历出来了,如果不想遍历继承的属性,则可以添加hasOwnProperty()
判断
for(let key in child) {
if (child.hasOwnProperty(key)) {
console.log(key)
}
}
// 输出
// x
// y
for ... of
语句
基本语法
用于遍历可迭代对象,比如(Array
,Map
,Set
,String
),可迭代对象简而言之就是原型对象都有一个 @@iterator
方法,具体概念自行谷歌。
for (variable of iterable) {
statements
}
Object
不是可迭代对象,所以用for ... of
遍历对象时则会报错。
const obj = {x: 1}
for(const v of obj){ console.log(v) }
// Uncaught TypeError: obj is not iterable
实例
const array = [1, 2, 3]
for( const value of array) {
console.log(value)
}
循环map对象时,可以定义key值
const map = new Map([['x', 1], ['y', 2]])
for(const [k, v] of map) {
console.log(k, v)
}
// 输出
// x 1
// y 2
中断循环
以上总共介绍了五种循环的方式,但每种方式该如何中断循环呢?下面来介绍中断循环的几种常见方式:break
,continue
,return
。
label
语句
首先介绍下label
语句,这个语句不是用来中断循环的,而是一个语句标识符,为什么先介绍这个语句呢?因为后面介绍的break
,continue
语句后面都可以跟label
这个参数,所以我们先看看label
的用法。
基本语法
label :
statement
label
的值可以是任何的非保留字的 JavaScript 标识符, statement
可以是任意你想要标识的语句(块)。具体有什么用呢?我们看下面的例子
实例
break label
// 标记第一个循环语句
labelLoop:
for (let i = 0; i < 3; i++) {
// 标记第二个循环语句
labelLoop2:
for(let j = 0; j < 3; j++) {
if(i === 1 && j === 0) {
break labelLoop;
// 直接跳出第一个循环,然后执行循环后面的语句
}
console.log(i, j);
}
}
console.log('end loop')
// 输出
// 0 0
// 0 1
// 0 2
// end loop
可以看出有label
标记后,可以直接跳出到标记循环外,执行循环后面的语句,如果没有label
则默认跳出当前循环。
continue label
labelLoop:
for (let i = 0; i < 5; i++) {
// 标记第二个循环语句
labelLoop2:
for(let j = 0; j < 5; j++) {
if(i === 1 && j === 0) {
continue labelLoop;
// 直接跳到第一个循环,然后执行第一个循环的下一次循环
}
console.log(i, j);
}
}
console.log('end loop')
// 0 0
// 0 1
// 0 2
// 2 0
// 2 1
// 2 2
// end loop
可以看出有label
标记后,可以直接跳出标记循环外,执行标记循环的下一次循环,如果没有label
则默认跳出当前循环,并执行当前循环的下一循环。
break
语句
终止循环或者switch
语句
基本语法
break [label]
如果省略label则中断当前循环或者switch
,如果有label
,则终止指定的label
语句
实例
-
for
语句中断循环
for (let i = 0; i < 5; i++) {
if(i > 2) { break; }
console.log(i);
}
// 输出
// 0
// 1
// 2
-
while
语句中断循环
let i = 0
while (i < 5) {
if(i > 2) { break; }
console.log(i);
i++
}
// 输出
// 0
// 1
// 2
-
do ... while
语句中断循环
let i = 0
do {
if(i > 2) { break; }
console.log(i);
i++
} while (i < 5)
// 输出
// 0
// 1
// 2
-
for ... in
语句中断循环
let obj = {x: 1, y: 2, z: 3}
for(let k in obj) {
if(k === 'z') { break;}
console.log(k)
}
// 输出
// x
// y
-
for ... of
语句中断循环
const arr = [1, 2, 3, 4, 5]
for(let v of arr) {
if(v > 2) { break; }
console.log(v)
}
// 输出
// 1
// 2
break
跟label
的实例请参考上方 break label 实例。
continue
语句
continue
语句用来跳过代码块的剩余部分并进入下一循环。
基本语法
continue [label]
如果省略label
则中断当前循环并进入下一次循环,如果有label
则进入被label
标识的下一次循环语句。
实例
for (let i = 0; i < 3; i++) {
if(i === 1) {
continue;
}
console.log(i);
}
// 输出
// 0
// 2
continue
跟label
的实例请参考上方 continue label实例。其他几种循环的continue
效果一致,就不在重复了。
return
语句
return
语句用于指定函数返回的值且return
语句只能出现在函数体内。
function loop() {
let i = 0
while(i < 5) {
if(i > 2) return
console.log(i)
i++
}
console.log('end')
}
loop()
// 输出
// 1
// 2
forEach
语句
forEach()
方法对数组的每个元素执行一次提供的函数。forEach
是数组原型上的一个遍历方法,这里拿出来讲主要是因为这也是一个非常常见的循环方法,而且经常会跟上面的循环搞混。
主要区别在于:没有办法中止或者跳出 forEach() 循环,除了抛出一个异常。如果你需要跳出循环请考虑使用for ... of
语句,或其他数组方法,比如:Array.prototype.every()
,Array.prototype.some()
等。
function test() {
var a = [1, 2, 3, 4, 5]
a.forEach(v => {
if(v===2) return
console.log(v)
})
console.log('end')
}
test()
// 输出
// 1
// 3
// 4
// 5
// end
可以看出return
无法中断forEach
循环。
总结
-
for ... in
循环会遍历自身和原型上的可枚举属性。 -
break
表示跳出循环。 -
continue
表示跳出当前循环,然后进入下次循环。 -
return
用在函数体内,终止函数的执行,并返回一个指定的值给函数调用者。 -
break
,continue
,return
都可用在for
,for ... in
,for ... of
,while
,do ... while
语句内。 -
forEach
语句除了抛出异常否则无法跳出循环,如果需要中断循环,则应考虑其他循环方式。