js 常見for循環以及跳出循環的總結

for語句

基本語法

for循環是大家非常熟悉的也經常用的一種寫法,一個for語句的基本語法為

// 括號中的三個條件都可省略
for ([initialExpression]; [condition]; [incrementExpression])
  statement

condition為true時,執行順序:

initialExpression->condition->statement->incrementExpression

  1. initialExpression

初始化表達式,可以是一個任意復雜度的表達式,也可以聲明變量。

// 常見用法1
for(let i = 0; i < 3; i++) { ... }
// 常見用法2
for(let i = 0, j = 3; i < j; i++) { ... }
  1. condition

執行for循環的條件表達式,如果值為true,循環中的語句會被執行,如果值為false,for循環終止。如果condition語句被省略,默認為true。

// condition默認為true,所以下面語句會進入死循環
for(;;) { ... }
  1. statement

for循環的執行體。

  1. 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語句

基本語法

用于遍歷可迭代對象,比如(ArrayMapSetString),可迭代對象簡而言之就是原型對象都有一個 @@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

中斷循環

以上總共介紹了五種循環的方式,但每種方式該如何中斷循環呢?下面來介紹中斷循環的幾種常見方式:breakcontinuereturn

label語句

首先介紹下label語句,這個語句不是用來中斷循環的,而是一個語句標識符,為什么先介紹這個語句呢?因為后面介紹的breakcontinue語句后面都可以跟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

breaklabel的實例請參考上方 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

continuelabel的實例請參考上方 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循環。

總結

  1. for ... in循環會遍歷自身和原型上的可枚舉屬性。
  2. break表示跳出循環。
  3. continue表示跳出當前循環,然后進入下次循環。
  4. return用在函數體內,終止函數的執行,并返回一個指定的值給函數調用者。
  5. breakcontinuereturn都可用在forfor ... infor ... ofwhiledo ... while語句內。
  6. forEach語句除了拋出異常否則無法跳出循環,如果需要中斷循環,則應考慮其他循環方式。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容