哪一种循环最快:https://mp.weixin.qq.com/s/yX_cOykgJvCRRI26q2xFOQ

一、循环,是一种重复运行同一代码的方法

循环

一、JavaScript提供了这些循环语句

  1. for语句
  2. while语句
  3. do…while语句
  4. labeled语句
  5. break语句
  6. continue语句
  7. for…in 语句
  8. for..of 语句

二、所有的“for”结构体都允许我们在循环中定义变量。

| 【示例】```javascript for (let key in user) {}

  1. |
  2. | --- |
  3. <a name="jLUL3"></a>
  4. ## for语句
  5. 一、一个for循环会一直重复执行,直到指定的循环条件为false。<br />二、for语句
  6. ```javascript
  7. for ([initialExpression] / [begin]; [condition]; [incrementExpression] / [step]) {
  8. statement / body / 循环体
  9. }

三、当一个for循环执行的时候,会发生以下过程
1、如果有初始化表达式initialExpression,它将被执行。
(1)这个表达式通常会初始化一个或多个循环计数器。
(2)这个表达式也可以声明变量。
2、计算condition表达式的值。
(1)如果condition的值是true,循环中的语句会被执行。
(2)如果condition的值是false,for循环终止。
(3)如果condition表达式整个都被省略掉了,condition的值会被认为是true。
3、循环中的statement被执行。
(1)如果需要执行多条语句,可以使用块{…}来包裹这些语句
4、如果有更新表达式incrementExpression,执行更新表达式。
5、回到步骤2

| 【示例】```javascript // for (let i = 0; i < 3; i++) alert(i)

// 开始 let i = 0 // 如果条件为真,运行下一步 if (i < 3) { alert(i); i++ } // 如果条件为真,运行下一步 if (i < 3) { alert(i); i++ } // 如果条件为真,运行下一步 if (i < 3) { alert(i); i++ } // ……结束,因为现在 i == 3

 |
| --- |


<a name="Og8Zm"></a>
### 省略语句段
一、for循环的任何语句段都可以被省略。

| 【示例】如果我们在循环开始时不需要做任何事,我们就可以省略begin语句段。```javascript
let i = 0; // 我们已经声明了 i 并对它进行了赋值

for (; i < 3; i++) { // 不再需要 "begin" 语句段
  alert( i ); // 0, 1, 2
}

| | —- |

| 【示例】也可以移除step语句段:```javascript let i = 0;

for (; i < 3;) { alert( i++ ); }

1、该循环与while (i < 3)等价。 |
| --- |

| 【示例】实际上我们可以删除所有内容,从而创建一个无限循环:```javascript
for (;;) {
  // 无限循环
}

1、请注意for的两个;必须存在,否则会出现语法错误。 | | —- |

while语句

一、一个while语句只要指定的条件为真(true)就会一直执行它的语句块。
二、while语句 / 语法

while (condition) {
  statement
}

三、执行过程
1、计算condition表达式的值
(1)如果条件返回为真(true),statement会被执行并紧接着再次测试条件。
(2)如果条件返回为假(false),执行将停止并把控制权交回给while后面的语句。
2、循环体的单次执行叫作一次迭代。

| 【示例】只要n小于3,下面的while循环就会一直执行```javascript var n = 0 var x = 0 while (n < 3) { n++ x += n }

1、每次循环,n会增加1,并被加到x上。所以,x和n的变化是:<br />第一次完成后,n = 1, x = 1<br />第二次完成后,n = 2, x = 3<br />第三次完成后,n = 3, x = 6<br />在第三次完成后,条件n < 3的结果不再为真,所以循环终止了。<br />2、上面示例的循环进行了三次迭代。 |
| --- |

四、任何表达式或变量都可以是循环条件,而不仅仅是比较。在while中的循环条件会被计算,计算结果会被转化为布尔值。

| 【示例】while (i != 0)可简写为while (i):```javascript
let i = 3;
while (i) { // 当 i 变成 0 时,条件为假,循环终止
  alert( i );
  i--;
}

| | —- |

| 【示例】分析下面代码块,输出( )行########。```javascript var i = 0; while( i < 40 ){ console.log(‘1’); if( i < 30 ) continue; Document.write(‘########’); i++; }

A. 40<br />B. 30<br />C. 39<br />D. 无数行<br />E. 一行也没有<br />答案:E<br />解析:conutine可用于for if while 语句中,表示跳出本次循环(break表示跳出循环,本次循环之后的都不执行),所以没有执行i++语句,i永远为0变成了死循环 |
| --- |

五、通常使用while(true)来构造“无限”循环。
<a name="hwu2R"></a>
## do...while语句
一、do...while语句一直重复直到指定的条件求值得到假值(false)。<br />二、do...while语句
```javascript
do {
  statement
} while (condition)

三、执行过程
1、statement被执行
(1)statement在检查条件之前会执行一次。
2、进行条件检查,计算condition表达式的值
(1)如果condition未真(true),statement将再次执行。
(2)当condition为假(false),执行会停止并且把控制权交回给do…while后面的语句。
3、回到步骤1
四、在每个statment执行的结尾都会进行条件的检查。
五、要执行多条语句(语句块),要使用块语句{…}包括起来。
六、这种形式的语法很少使用,除非你希望不管条件是否为真,循环体至少执行一次。通常我们更倾向于使用另一个形式:while(…) {…}

for…in语句

一、for…in语句循环一个指定的变量来循环一个对象所有可枚举的属性。JavaScript会为每一个不同的属性执行指定的语句。
二、for…in语句

for (variable in object) {
    statements
}

三、for…in迭代数组时,返回的东西除了数字索引外,还有可能是你自定义的属性的名字。
三、for…in迭代对象

| 【示例】```javascript let user = { name: “John”, age: 30, isAdmin: true };

for (let key in user) { // keys alert( key ); // name, age, isAdmin // 属性键的值 alert( user[key] ); // John, 30, true }

 |
| --- |


<a name="ZvlPf"></a>
## for...of语句
一、for...of 语句在可迭代对象(如Array, Map, Set, arguments等)上创建了一个循环,对值的每一个独特属性调用一次迭代。<br />二、for...of语句
```javascript
for (variable of object) {
    statement
}

三、for…of、for…in两种语句之间的区别:
1、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"
}

// 注意 for...of 的输出没有出现 "hello"

forEach

一、forEach不能终止循环(使用break 或return 语句)

const arr = [1, 2, [3, 4]]

t1(arr)
t2(arr)

function t1 (arr) {
  for (let item of arr) {
    console.log('for...of, 之前:', item) // 1
    if (item === 1) {
      return true
    }
  }
}

function t2 (arr) {
  arr.forEach ((item) => {
    console.log('forEach,之前:', item) // 共打印了3次,分别是1、2、[3、4]
    if (item === 1) {
      return true
    }
  })
}

label语句

一、一个label提供了一个让你在程序中其他位置引用它的标识符。
二、可以用label标识一个循环,然后使用break或continue来指出程序是否该停止循环还是继续循环。
三、标签label是在循环之前带有冒号的标识符
2、label语句语法

labelName: for (...) {
  ...
}

1、label的值可以是任何的非保留字的javascript标识符,statement可以是任意你想要标识的语句(块)
四、标签并不允许跳到代码的任意位置

| 【示例】这样做是不可能的:```javascript break label; // 无法跳转到这个标签

label: for (…)

 |
| --- |

1、只有在循环内部才能调用break/continue,并且标签必须位于指令上方的某个位置。<br />五、break/continue支持循环前的标签。标签是break/continue跳出嵌套循环以转到外部的唯一方法。

| ☆【示例】未添加label<br />1、break```javascript
var num = 0;
for (var i = 0 ; i < 10 ; i++) {   // i 循环
  for (var j = 0 ; j < 10 ; j++) { // j 循环
    if( i == 5 && j == 5 ) {
       break; // i = 5,j = 5 时,会跳出 j 循环
    } // 但 i 循环会继续执行,等于跳出之后又继续执行更多次 j 循环
      num++;
  }
}

alert(num); // 输出 95

2、continue```javascript var num = 0; for (var i = 0 ; i < 10 ; i++) { // i 循环 for (var j = 0 ; j < 10 ; j++) { // j 循环 if( i == 5 && j == 5 ) { continue; // i = 5, j = 5时,会不执行下面的num++,但是不会退出j循环,而是以i = 5, j = 6继续执行j循环 } num++; } }

alert(num); // 输出 99

 |
| --- |

| ☆【示例】添加label,标记outPoint标识了一个for循环<br />1、break <labelName>语句跳出循环至标签处```javascript
var num = 0;
outPoint:
for (var i = 0 ; i < 10 ; i++){
  for (var j = 0 ; j < 10 ; j++){
    if( i == 5 && j == 5 ){
      break outPoint; // 在 i = 5,j = 5 时,跳出所有循环,
                      // 返回到整个 outPoint 下方,继续执行
    }
    num++;
  }
}

alert(num); // 输出 55

2、break outer向上寻找名为outer的标签并跳出当前循环```javascript outer: for (let i = 0; i < 3; i++) {

for (let j = 0; j < 3; j++) {

let input = prompt(`Value at coords (${i},${j})`, '');

// 如果是空字符串或被取消,则中断并跳出这两个循环。
if (!input) break outer; // 控制权直接从这里转至 alert('Done!')

// 用得到的值做些事……

} } alert(‘Done!’);

 |
| --- |

| ☆【示例】使用continue语句,可达到与未添加label(break)相同的效果。<br />continue指令与标签一起使用,执行跳转到标记循环的下一次迭代。<br />有多层循环的情况下,添加label后,循环的跳出进入流程更为清晰一些。```javascript
var num = 0;
outPoint:
for(var i = 0; i < 10; i++) {
  for(var j = 0; j < 10; j++) {
    if(i == 5 && j == 5) {
      continue outPoint;
    }
    num++;
  }
}
alert(num);  // 95

| | —- |

跳出循环

一、通常条件为假时,循环会终止。
二、但我们随时都可以使用break指令强制退出。

break语句

一、使用break语句来终止循环,switch,或者是链接到label语句
1、不带label的break,会立即终止当前所在的while, do-while, for, 或者switch并把控制权交回这些结构后面的语句。
2、带label的break,会终止指定的带标记(label)的语句
二、break语法

break [label] // []包裹的内容表示可省略

| 【示例】如果用户输入空行或取消输入,在()行的break指令会被激活。它立刻终止循环,将控制权传递给循环后的第一行,即,alert。```javascript let sum = 0; while (true) { let value = +prompt(“Enter a number”, ‘’); if (!value) break; // () sum += value; } alert( ‘Sum: ‘ + sum );

 |
| --- |

三、"无限循环 +break" 的组合非常适用于不必在循环开始/结束时检查条件,但需要在中间甚至是主体的多个位置进行条件检查的情况。
<a name="FvAge"></a>
# 继续下一次迭代
一、continue指令是break的“轻量版”。它不会停掉整个循环。而是停止当前这一次迭代,并强制启动新一轮循环(如果条件允许的话)。
<a name="OEUH1"></a>
## continue语句
一、continue语句可以用来继续执行(跳过代码块的剩余部分并进入下一个循环)一个while、do...while、for,或者label语句。<br />1、不带label的continue,终止当前while, do...while,或者for语句到结尾的这次的循环并且继续执行下一次循环。<br />2、带label的congtinue,会应用被label标识的循环语句。<br />二、continue语法
```javascript
continue [label]

| 【示例】下面这个循环使用continue来只输出奇数:```javascript for (let i = 0; i < 10; i++) { //如果为真,跳过循环体的剩余部分。 if (i % 2 == 0) continue; alert(i); // 1,然后 3,5,7,9 }

 |
| --- |

三、continue指令利于减少嵌套

| 【示例】显示奇数的循环可以像下面这样:```javascript
for (let i = 0; i < 10; i++) {

  if (i % 2) {
    alert( i );
  }
}

1、从技术角度看,它与上一个示例完全相同。当然,我们可以将代码包装在if块而不使用continue。
2、但在副作用方面,它多创建了一层嵌套(大括号内的alert调用)。如果if中代码有多行,则可能会降低代码整体的可读性。 | | —- |

四、禁止break/continue在 ‘?’ 的右边
1、请注意非表达式的语法结构不能与三元运算符?一起使用。特别是break/continue这样的指令是不允许这样使用的。

| 【示例】我们使用如下代码:javascript if (i > 5) { alert(i); } else { continue; } // 用问号重写: (i > 5) ? alert(i) : continue; // continue 不允许在这个位置 1、代码会停止运行,并显示有语法错误。
2、这是不(建议)使用问号?运算符替代if语句的另一个原因。 | | —- |