ECMAScript/ES6循环

ECMAScript/ES6循环

编程语言中的循环语句用于在条件评估为true时重复执行指令/功能集。 循环是重复执行某些条件的理想方法。 在循环中,重复称为迭代。

在下图中看到循环的分类:

下面我们来详细了解上图中的每种循环。

1.定义循环

确定循环具有确定/固定的迭代次数。 在ES6中,下面列出了三种类型的定环:

定义循环 说明
for(;;) 循环它执行代码块一定次数。
for…in 循环迭代对象的属性。
for…of 循环与对象文字不同,它迭代可迭代对象(数组,字符串等)。

1.1.for(;;)循环

for(;;)循环用于多次迭代程序的一部分。 如果迭代次数固定,则始终建议使用for循环。

语法

for(initialization;condition;incr/decr){    
    statments;// 语句或要执行的代码   
}

for循环包括一些定义如下的部分:

  • 初始化(initialization):这是在循环开始时执行一次的初始条件。 在这一部分中将初始化变量,或者也可以将其用于已初始化的变量。这是一个可选语句。
  • 条件(condition):每次都要执行一次,以测试循环的条件。 它继续执行循环,直到条件为false。它仅返回为truefalse的布尔值。这也是一个可选语句。
  • 递增/递减(incr/decr):可以递增或递减变量的值,它也是可选语句。
  • 语句(statments):它表示循环的主体,每次在条件表达式为false之前执行。

for循环流程图:

在下面的for循环的三个示例中,演示了如何使用简单的for循环,具有多个表达式的for循环和无限的for循环。

  1. 使用简单for循环
var i;  
for(i=1;i<=10;i++)  
{  
   console.log("2 x "+ i +" =", 2*i);  
}

执行上面示例代码,得到以下结果:

2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
2 x 10 = 20
  1. 具有多个表达式的for循环

可以使用逗号(,)运算符在一个for循环中组合多个赋值和最终表达式。下面演示如何通过使用单个for循环来打印Fibonacci数列。

"use strict"   
for(let temp, a = 0, b = 1; b<40; temp = a, a = b, b = a + temp)   
console.log(b);

执行上面示例代码,得到以下结果:

1
1
2
3
5
8
13
21
34
  1. 无限循环

无限for循环的示例如下:

for(;;)  
{    
   console.log("infinitive loop");  // It will print infinite times  
}

执行上面示例代码,得到以下结果:

infinite loop
infinite loop
infinite loop
infinite loop
infinite loop
infinite loop
infinite loop
infinite loop
infinite loop
infinite loop
infinite loop
infinite loop
    .
    .
    .
    .
infinite loop

注:要终止它,可以按住:ctrl + c

1.2.for…in循环

for…in循环类似于for循环,它循环访问对象的属性,即,当需要访问对象的属性或键时,可以使用for…in循环。 当使用索引顺序不是必需的对象或字典时,这是一个更好的选择。

语法

for (variable_name in object_name) //Here in is the keyword  
{    
  // statement or block to execute    
}

在每次迭代中,将对象的一个属性分配给变量的名称,并且此循环一直进行到所有对象属性都被覆盖为止。

示例

function Mobile(model_no){  
    this.Model = model_no;  
    this.Color = 'White';  
    this.RAM = '8GB';  
}  
var Samsung = new Mobile("Galaxy");  
for(var props in Samsung)  
{  
    console.log(props+ " : " +Samsung[props]);  
}

执行上面示例代码,得到以下结果:

Model : Galaxy
Color : White
RAM : 8GB

如果在对象的属性中传递函数,则此循环将在输出中提供完整的函数。可以在以下代码中进行说明:

function Mobile(model_no){  
this.Model = model_no;  
this.Color = 'White';  
this.RAM = '8GB';  
this.Price = function price() // The loop will give you this function as it is written here.  
{  
   console.log(this.model + "Price = RMB 3300");  
}  
}  
var Samsung = new Mobile("Galaxy");  
for(var props in Samsung)  
{  
   console.log(props+ " : " +Samsung[props]);  
}

执行上面示例代码,得到以下结果:

Model : Galaxy
Color : White
RAM : 8GB
Price : function price()
{
   console.log(this.model + "Price = RMB 3300");
}

因此,您也可以使用for…in循环访问这些方法。

1.3.for…of循环

与对象文字不同,此循环用于迭代可迭代对象(数组,字符串等)。

语法

for(variable_name of object_name) // Here of is a keyword  
{    
   //statement or block to execute    
}

在每次迭代中,将来自可迭代对象的一个属性分配给variable_name,然后循环继续进行直到迭代结束。

示例代码

var fruits = ['Apple', 'Banana', 'Mango', 'Orange'];  
for(let value of fruits)  
{  
  console.log(value);   
}  

/* 另外的写法 : 

for(let value of ['Apple', 'Banana', 'Mango', 'Orange']) 
{ 
  console.log(value);  
} 

*/

执行上面示例代码,得到以下结果:

Apple
Banana
Mango
Orange

2.不定循环

无限循环具有无限迭代,当循环内的迭代次数介于中间或未知时使用。

下面列出了两种类型的不定循环:

不定 循环说明
while循环 每次执行指令,直到定义的条件为真。
do…while循环 while循环相似,但主要区别在于do...while循环不考虑终止条件而立即执行循环。

2.1.while循环

while循环是一个控制流语句,它允许根据给定的布尔条件重复执行代码。 它由一个代码块和一个表达式/条件组成。while循环在执行块之前检查表达式/条件;这种控制结构通常也称为预测试循环。

语法

while (condition) {  
   statements;  
}

while循环语句的流程图如下:

示例代码:

var y = 0;  
while (y < 4) {  
    console.log("value of y is :"+y);  
    y++;  
}

执行上面示例代码,得到以下结果:

D:\es6>node while-loop.js
value of y is :0
value of y is :1
value of y is :2
value of y is :3

注意:

while循环中始终需要测试条件,才决定能不能运行循环。 如果条件返回true,则循环将重新开始,但是如果返回false,则循环将停止。
如果条件始终为真,则循环永远不会结束。

2.2.do…while循环

这是一个控制流语句,至少执行一次代码块,然后将取决于条件是否循环重复执行该代码块。
do…while循环在执行完块后检查条件,这就是为什么此控制结构也称为后测试循环的原因。条件也可能总是评估为true,那么将创建一个无限循环。

语法

do   
{    
  // block of statements to be executed;    
}   
while (expression);

do…while循环流程图:

示例代码

var count = 6, fact = 1;  
do {  
    fact = fact * count--;  
} while (count > 0);  

console.log(fact);

执行上面示例代码,得到以下结果:

720

如果使用while循环执行此示例,那么它将写为:

var count = 6, fact = 1;  
while (count > 0)   
{  
    fact = fact * count--;  
}  
console.log(fact);

执行上面示例代码,得到以下结果:

720

上面两个示例之间的主要区别在于,仅当传递给它的条件为真时才进入while循环。但是do … while循环只执行一次该语句,因为do … while循环的开始迭代才发生,所以它不会被视为布尔表达式。然后,对于进一步的迭代,while将检查条件并将控制从循环中取出。

3.循环控制语句

循环控制语句用于中断或控制执行流程。这些语句从其正常顺序更改执行。 JavaScript提供了处理循环和switch语句的完整流程。
在某些情况下,可能需要从循环中走出来而不到达最低点。在某些情况下,我们需要跳过部分代码并开始循环的进一步迭代。在JavaScript中可以使用breakcontinue语句处理这种情况。

循环控制 语句说明
break语句 break语句用于使程序的控制脱离循环。
Continue语句 跳过当前迭代的后续语句,并将程序的控制带到循环的开始。

让我们来了解如何使用上述控制语句。

3.1.break语句

它用于从循环中控制程序,可以在循环内或switch语句中使用break语句。 在循环中使用break语句会使程序退出循环。

语法

break;

示例代码:

var n = 1;  
while(n<=7)   
{   
   console.log("n="+n);   
   if(n==4)  
   {  
       break;  
   }   
   n++;  
}

上面的代码将为17之间的数字范围打印n的四个值。

n的值为4时,由于执行了break语句,循环强制控件退出循环。 成功执行以上代码后,将得到以下输出。

n=1
n=2
n=3
n=4

3.2.continue语句

break语句不同,continue语句不会从循环中退出。它终止循环的当前迭代并开始下一个迭代。

语法

continue;

示例:

var n = 0;  
while(n<=5)   
{   
   n++;  
   if(n==3)  
   {  
       continue;  
   }   
   console.log("n => "+n);   
}

上面的示例将显示n的值,但是如果n的值为3,它将跳过当前迭代。成功执行上述代码后,将获得以下输出。

n => 1
n => 2
n => 4
n => 5
n => 6

4.使用标签控制流程

标签可以理解为是一种标识符,后跟冒号(:),并应用于代码块或语句。可以使用标签休息一下,然后继续控制流程。不能在breakcontinue语句及其标签名称之间使用换行符。 另外,标签名称和关联的循环之间不应有任何语句。

定义标签的语法

labelname:  
Statement

labelname:JavaScript的任何标识符,但不能是保留字。
Statement:这是一个JavaScript语句。

注意:在严格模式下,不能使用let作为标签名称。 因为let是保留的标识符,这将导致语法错误。

标签 说明
break语句的标签 它用于不使用标签引用而从循环或switch语句退出,但具有标签引用时,可用于从任何代码块跳出。
continue语句的标签 用于在使用或不使用标签引用的情况下跳过循环的一次迭代。

4.1. 带有break语句的标签

在不使用标签引用的情况下,可以仅使用中断从循环或从switch退出,但是通过使用标签引用,可以使用中断从任何代码块跳出。

语法

break labelname;

示例代码

var x, y;  

loop1:         //The first for statement is labeled as "loop1."  

for (x = 1; x < 4; x++) {   
     loop2:    //The second for statement is labelled as "loop2"  
   for (y = 1; y < 4; y++) {    
      if (x === 2 && y === 2) {  
         break loop1;  
      }  
      console.log('x = ' + x + ', y = ' + y);  
   }  
}

执行上面示例代码,得到以下结果:

x = 1, y = 1
x = 1, y = 2
x = 1, y = 3
x = 2, y = 1

4.2.带有continue语句的标签

continue语句仅可用于使用标签引用或不使用标签引用来跳过一个循环迭代。

语法:

continue labelname;

示例代码

var x, y;  

loop1:   //The first for statement is labelled as "loop1"  
for (x = 1; x < 4; x++) {       
   loop2:  //The second for statement is labelled as "loop2"  
   for (y = 1; y < 4; y++) {     
      if (x === 2 && y === 2) {  
         continue loop1;  
      }  
      console.log('x = ' + x + ', y = ' + y);  
   }  
}

如下输出结果中,执行代码时程序将跳过:"x = 2, y = 2""x = 2, y = 3"

x = 1, y = 1
x = 1, y = 2
x = 1, y = 3
x = 2, y = 1
x = 3, y = 1
x = 3, y = 2
x = 3, y = 3

4.3.带标签的函数声明

在ECMAScript 6之前,LabeledStatement规范不允许将label语句与FunctionDeclaration关联。 但是,标为FunctionDeclaration是非严格代码中允许的扩展,并且大多数由ECMAScript浏览器托管的实现均支持该扩展。

但是在ECMAScript 2015(ES6)中,LabeledStatement的语法生成允许使用FunctionDeclaration作为LabeledItem,但是它包含一个错误规则,如果发生该错误会导致语法错误。

为了与Web浏览器兼容,该规则通过添加带下划线的文本进行了修改:

LabeledItem : FunctionDeclaration

如果任何严格模式的源代码都匹配此规则,将导致语法错误。

从ECMAScript 2015开始,带标签的函数声明针对非严格代码进行了标准化:

L: function hello() {}

If you write the above code in strict mode then this will throw a syntax error:

'use strict';  
L: function hello() {}  
// SyntaxError: 在严格模式代码中,只能在顶层或块内声明函数。

不能在非严格模式或严格模式下标记生成器函数。

L: function* hello()   
{  
}  
// SyntaxError: Generator Functions cannot be labelled