一般来说ECMAScript中的大部分语法都体现在流程控制(也可称为语句)中,流程控制通常使用一个或多个关键字完成即定任务,它可简单也可复杂。分为分支结构、循环结构、跳转结构等。
一、分支结构
分支结构语句是通过判断指定表达式的值来决定执行还是跳过某些语句,这些语句是代码的“决策点”有时称之为“分支”。它一般分为if语句和switch语句。
- if语句
if语句是一种基本的控制语句,它让Javascript程序可以选择执行路径,简单来说就是有条件的执行语句。它是使用最频繁的语句之一。
if (expression){
statement1;
} else {
statement2;
}
if语句的判断条件expression必须放在if后面的圆括号内,它可以是任意表达式,其求值结果不一定是布尔值,因为ECMAScript会自动调用Boolean()函数将这个表达式的值转换为布尔值。如果转换为true则执行statement1语句;如果为false则执行statement2语句。statement1和statement2可能是一行代码,也可以是一个代码块。花括号不为必须,如果花括号内只有一条语句,可以省略花括号,但为了提高代码可读性不建议省略。
a. if语句:它是最简单的条件语句;
b. if...else语句:它是if语句的第二种形式引入了else从句。当在if...else语句中嵌套使用if语句时,要注意确保else语句匹配正确的if语句。javascript中if...else匹配规则是:else总是和就近的if语句进行匹配;
c. else if语句:当代码有多条分支时用到这个语句。
//1.如果只有一种情况要处理
if(expression) { statement;}
//2.有两种情况要处理
if(expression){
statement1;
}else{
statement2;
}
//3.有多种情况要处理
if(expression1){
statement1;
}else if(expression2){
statement2;
}else if(expression3){
statement3;
}else{
statement4;
}
- switch语句
当所有分支都依赖于同一个表达式的值可以用到switch语句。
switch语句执行一个多路分支,首先计算expression值,然后进行查找。查找case子句的表达式是否和expression的值相同。如找到匹配的case,那么将执行这个case相对应的代码块,如果找不到匹配的case,那它将会执行default标签中的代码块,如果没有default标签,switch语句将跳过它的所有代码块。
switch (expression) {
case value1:
statement1;
break;
case value2:
statement2;
break;
......
case valuen:
statementn;
break;
default:
statement
}
每一个case语句块的结尾要使用关键字break或者是return,不然switch语句就会从与expression的值相匹配的case标签处代码块开始执行,依次执行后续语句,一直到整个switch代码块结束(不会跳出switch语句)。如果确实需要连续匹配几个条件,最好写个注释表明是故意忽略break。
在switch语句可以用于所有数据类型。它可以使用字符串甚至是对象。且每个case的值不一定是常量,可以是变量或表达式。
switch ("hello world"){
case 'hello' + 'world':
console.log('greeting was found.');
break;
case 'goodbye':
console.log('closing was found.');
break;
default:
console.log('unexpected message was found.')
}
在使用switch语句中,要注意以下几点:
a.由于每次执行switch语句时,并不是所有的case表达式都能够执行到,所以要避免使用带有副作用的case表达式,最安全做法是在case表达式中使用常量表达式。
b.default标签一般出现在末尾(特殊情况也可以在switch语句中任何位置)
c.switch语句中,对每个case的匹配操作实际上是“===”恒等运算符比较而不是“==”相等运算符比较,因此表达式和case的匹配不会做任何类型转换。
二、循环语句
javascript有以下种循环语句:**while、do...while、for、for...in、for...of。**只要给定条件仍能得到满足,包含在循环语句里的代码就将重复执行下去。一旦给定条件的求值结果不再是true,循环也就到此为止。其中最常用的循环就是对数组元素的遍历。
- while语句
while语句属于先测试循环语句,在循环体内的代码被执行之前,就会对条件进行判断。
while (expression) { statement; }
当表达式expression为true时则循环执行statement,直到expression的值为false为止;如果是false,那么程序将跳过循环。
注意:当while条件不具备停止条件的时候,一定要在循环体内给一个条件让其变化不然就是一个死循环。
while和for的区别:while循环是一个条件循环,它一般用在有嵌套的元素或者是有嵌套的数据。一般来说要执行循环操作首先考虑for循环如果for循环做不出来或者是做出来麻烦那就用while循环。
- do...while循环
do while语句是后测试循环,它是在循环的尾部而不是顶部检测循环表达式。这意味着在计算表达式之前,至少会执行循环主体一次。它会首先执行循环体,然后再计算条件表达式expression。如果表达式为真,则执行循环体,然后再计算表达式expression的值,这种循环会一直继续下去直到expression的值为假,循环结束。
do {
statement;
} while (expression);
do...while循环和普通while循环有以下区别:
a.while:先判断,再执行,所以循环有可能一次都不会执行;
b.do...while:它要求必须使用关键字do来标识循环的开始,用while来标识循环的结尾并进入expression判断。是先执行,后判断,所以不管任何情况它都至少会执行一次。
- for语句
for语句提供一个比while语句更加方便的循环控制结构。用for语句来重复执行需要循环的结构可以使之更加清晰。
for语句也是先测试语句。大部分的for都具有特定的变量。三个变量是:条件初始化(initialization),条件判断(expression),条件变化(post-loop-expression)。如下所示:
for(initialization;expression;post-loop-expression) statement
在for循环的初始化代码中,其实可以不使用变量声明关键字。但初始化定义的迭代器变量在循环执行完成后几乎不可能再用到,所以最清晰的写法还是使用let声明变量,这样就可以将这个变量的作用域限定在循环中。
初始化,条件表达式和循环后表达式其实都不是必需的。所以如下所示:
for(;;){//无穷循环
doSomething();
}
for循环常见用途是对某个数组里的全部元素进行遍历处理。如果循环中的一次迭代会改变多个变量,需要用逗号运算符,它将初始化表达式和自增表达式合并入一个表达式中以用于for循环。
有嵌套的循环,如果里面循环没有走完,外面的循环步骤是不会继续。需要注意里面的变量不要与外面的变量相同,如果相同里面的变量会把外面的变量给覆盖掉。
for (var i = 1; i < 10 && i > 0; i++) {
for (var j = 1; j <= i; j++) {
document.write(j + '*' + i + '=' + i * j + ' ')
}
document.write('<br>')
}
- for in语句
for...in语句也使用了for关键字,但它和for完全不一样。它是一种严格的迭代语句可以以任意顺序遍历一个对象除Symbol以外可枚举属性。
for (variable in object) statement
variable 在每次迭代时会被赋值为不同的属性名。它通常是一个变量名,也可以是表达式总之必须是一个适用于赋值表达式左侧的值。object是一个非Symbol类型的可枚举被迭代的对象。statement是一个语句或者是语句块,它是循环的主体。
//这里的const不是必需,但为了确保这个局部变量不被修改,所以用const
for (const propName in window){
document.write(propName + '<br>');
}
ECMAScript中对象的属性是无序,所以for...in语句不能保证返回对象属性的顺序,不建议使用for...in遍历数组,输出顺序不固定。如果for...in循环要迭代的变量是null或undefined,则不执行循环,建议在使用for...in循环前对这个对象的值是不是null或者undefined进行判断。
- for of语句
for...of语句是一种严格迭代语句,用于遍历可迭代对象的元素,
for (variable of iterable){
statement
}
variable它是每次迭代中将不同属性的值分配给变量,iterable被迭代枚举其属性的对象。
let iterable = [10,20,30,40];
for (const value of iterable){
console.log(value);
}
for...of和for...in的区别在于for...in语句它以任意顺序迭代对象的可枚举属性,而for...of语句遍历可迭代对象定义要迭代的数据。
三、跳转语句
跳转语句要让解释器跳转到程序的其它部分继续执行。它们为执行循环代码提供了更加严格的控制手段。分别为:break、return和continue。
- break语句
单独break语句是退出最内层循环,停止循环下面的循环就不会走了。break后面的代码是不会执行的。它只有出现在循环语句或者是switch语句中才算是合法,出现在其他的语句中会报错。
for(var i = 0;i<5;i++){
if(i==3){
break;
}
console.log(i);
}
- continue
continue声明终止当前循环或标记循环的当前迭代中语句执行,并在下一次迭代时继续执行循环。
当执行到continue语句时,当前的循环逻辑就终止了,随即执行下一次循环。但在不同类型的循环中,continue行为也有所不同:
a.while循环中,循环开始处指定的expression会重复检测,如果检测结果为true,则循环体会从头开始执行;
b.do while循环中,程序执行直接跳到循环结尾处,这时会重新判断循环条件,之后才会继续下一次循环;
c. for循环中控制流跳转到更新语句。
for (var n = 1; n < 5; n++) {
if (n === 3) continue; console.log(n); //1 2 4
}
- return
函数中的return语句就是指定函数调用后的返回值。让函数停止执行,它只能用在函数内。不然会报错。当执行到return语句时,函数终止执行,并返回expression的值给调用程序。
如果没有return语句,则函数调用仅仅依次执行函数体内的每一条语句直到函数结束,最后返回调用程序。这种情况下,调用表达式的结果是undefined。return语句经常作为函数内的最后一条语句出现,但并不是说一定要放在函数最后,即使在执行return语句的时候还有很多后续代码没有执行到,这时函数也还是会返回调用程序。