javascript语句——条件语句、循环语句和跳转语句

前面的话

  默认情形下,javascript解释器依据语句的编撰顺序依次执行。而javascript中的很多语句能够更改语句的默认执行顺序。本文介绍能够变更语句默认执行各种的基准语句、循环语句和跳转语句

 

标准化语句

  脚本的威力展现在它们得以按照人们给出的各类条件做出仲裁,javascript使用标准语句来做判断

  条件语句(conditianal
statement)通过判断表明式的值来决定履行或者跳过好几语句,包括if语句和switch语句

【if语句】

  最常见的规范语句是if语句。if语句的规范必须放在if后边的圆括号内,条件的求值结果永远是一个布尔值,即只可以是true或false。花括号中的语句,不管它们有稍许条,只有在加以条件的求值结果是true的情事下才会履行

if(expression){
    statements;
}

  [注意]if语句中,括住expression的圆括号在语法上是必要的

  实际上,if语句中的花括号不是不可或缺的。假使if语句中的花括号部分只含有一条语句,可以不拔取花括号。但因为花括号可以提升脚本的可读性,所以在if语句中总是拔取花括号是个好习惯

//可行,但不推荐
if(1>2)alert('1');

//推荐写法
if(1>2){
    alert('1');
}

  if语句依据表明式的值改变程序流程。当expression的值为true时施行跟在未来的代码块,当expression的值为false时,执行else的逻辑

if(expression)
    statement1
else
    statement2

  当在if/else语句中嵌套使用if语句时,必须注意确保else语句匹配正确的if语句

//错误暗示
if( i == j)
    if(j == k)
        console.log('i == k');
else console.log('i != j');

  javascript中的if/else匹配规则是:else总是和不远处的if语句匹配

//实际解释
if( i == j){
    if(j == k)
        console.log('i == k');
    else
        console.log('i != j');//错误
}

//使用花括号
if(i == j){
    if(j == k){
        console.log('i == k');
    }
}else{
    console.log('i != j');
}

  当代码有多条分支时,需要采用else if语句。else
if语句并不是真的的javascript语句,它是多条if/else语句连在一起时的一种惯用写法 

if(n == 1){
    //代码1
}else if(n == 2){
    //代码2
}else if(n == 3){
    //代码3
}else{
    //其他代码
}

  可以用if语句的嵌套格局来成功在语法上等价的代码,但一直不else
if语句清晰

if(n == 1){
    //代码1
}else{
    if(n == 2){
        //代码2
    }else{
        if(n == 3){
            //代码3
        }else{
           //其他代码
        }
    }
}

【switch语句】

  当有着的分层都依靠于同一个表明式的值时,else
if并不是最佳解决方案。在那种景色下,重复总括多条if语句中的条件表明式是特别浪费的做法,而switch语句正适合处理这种情况

  switch语句执行一个多路分段,首先统计expression的值,然后搜索case子句的表明式是否和expression的值相同。假诺找到匹配的case,那么将会执行那一个case对应的代码块。虽然找不到万分的case,那么将会实施default标签中的代码块。倘若没有default标签,switch语句将跳过它的保有代码块

switch (expression)
  case value1: statement1;
    break;
  case value2: statement2;
    break;
  case value3: statement3;
    break;
  default: statement4;

if(n == 1){
    //代码1
}else if(n == 2){
    //代码2
}else if(n == 3){
    //代码3
}else{
    //其他代码
}

//等价于
switch(n){
    case 1:
        //代码1
        break;
    case 2:
        //代码2
        break;
    case 3:
        //代码3
        break;
    default:
        //代码4
}

  每一个case语句块的结尾处都采用了第一字break。break语句能够使解释器跳出switch语句或循环语句

  在switch语句中,case只是指明了要实践的代码起源,但并从未指明终点。假如没有break语句,那么switch语句就会从与expression的值相匹配的case标签处的代码块开首实施,依次执行后续的口舌,一向到任何switch代码块的最终

//如果没有break语句,若switch语句匹配1,则不仅执行代码1,也会执行代码2和代码3
switch(n){
    case 1:
        //代码1
    case 2:
        //代码2
    default:
        //代码3
}

  假若真的需要混合二种状态,要在代码中添加注释,表达是假意省略了break关键字

switch(i){
    //合并两种情形
    case 25:
    case 35:
        console.log('25 or 35');
        break;
    case 45:
        console.log('45');
        break;
    default:
        console.log('other');
}

  即使在函数中运用switch语句,可以行使return来取代break,return和break都用于终止switch语句,也会制止一个case语句块执行完后继续执行下一个case语句块

//函数中使用switch语句
function convert(x){
    switch(typeof x){
        case 'number':
            return x.toString(16);
        case 'string':
            return '"' + x + '"';
        default:
            return String(x);
    }
}

  即便ECMAScript中的switch语句借鉴自其他语言,但这一个讲话也有投机的特色。能够在switch语句中行使此外数据类型(在诸多别样语言中不得不采纳数值),而且每个case的值不必然是常量,可以是变量或表明式

var num = 25;
switch(true){
    case num < 0:
        console.log('less than 0.');
        break;
    case num >=0 && num <=10:
        console.log('between 0 and 10.');
        break;
    case num >10 && num <=20:
        console.log('between 10 and 20.');
        break;
    default:
        console.log('more than 20.');
}

  使用switch语句时,要留心以下几点:

  【1】由于每一次执行switch语句时,并不是拥有的case说明式都能举办到,因而,应该避免使用含有副功效的case表明式,比如函数调用表明式和赋值表明式,最安全的做法是在case表明式中运用常量表明式

  【2】default标签一般都出现在switch的末梢,位于所有case标签之后,当然这是最合理也是最常用的写法,实际上,default标签可以放置在switch语句内的其余地点

  【3】switch语句中,对各种case的匹配操作实际是’===’恒等运算符相比较,而不是’==’相等运算符相比较,因而,表达式和case的匹配并不会做其他类型转换

//由于1并不会转换为'1',所以结果是3
var n = 1;
switch(n){
    case '1':
        console.log(1);
        break;
    case 2:
        console.log(2);
        break;
    default:
        console.log(3);
}

 

循环语句

  条件语句把javascript中的代码变成一条条的支行路径,而循环语句(looping
statement)就是先后路径的一个回路,可以让有些代码重复执行

  javascript有4种循环语句:while、do/while、for、for/in,它们的劳作规律几乎一致:只要给定条件仍是可以拿到满意,包含在循环语句里的代码就将重新地推行下去。一旦给定规则的求值结果不再是true,循环也就到此为止。其中最常用的轮回就是对数组元素的遍历

【while语句】

  while语句属于前测试循环语句,也就是说,在循环体内的代码被实践以前,就会对讲话原则求值

while(expression){
  statement
}

  当表明式expression是真值时则循环执行statement,直到expression的值为假值结束;即便是假值,那么程序将跳过巡回

  [注意]应用while(true)会创设一个死循环

  大多数循环都会有一个像count这样的计数器变量。尽管循环计数器常用i、j、k那样的变量名,但只要想要让代码可读性更强,就应有采用更具语义的变量名

var count = 0;
while(count < 10){
    console.log(count);
    count++;
}

【do while语句】

  do
while语句是后测试循环,即退出标准在履行循环之中的代码之后统计。这意味着在统计表明式从前,至少会执行循环主体两次

do{
    statement
}while(expression);

  do/while循环和普通的while循环有两点语法方面不比:

  【1】do/while循环要求必须利用首要字do来标识循环的启幕,用while来标识循环的最后并进入循环条件判断

  【2】do/while循环用分号结尾。倘使while循环体使用花括号括起来,则while循环也不用利用分号做最终

function printArray(a){
    var len = a.length,i=0;
    if(len == 0){
        console.log('empty');
    }else{
        do{
            console.log(a[i]);
        }while(++i<len);
    }
}

【for语句】

  for语句提供了一种比while语句更加便宜的轮回控制结构,用for循环来重复执行一些代码的好处是循环控制结构更加显然

  大部分的大循环都拥有一定的计数器变量,计数器的两个第一操作是初始化、检测和更新。for语句将这三步明确宣称为循环语法的一片段,各自行使一个表明式来表示

for(initialize;test;increment){
    statement;    
}

//等价于:
initialize;
while(test){
    statement
    increment;
}

  [注意]使用continue语句时,while循环和for循环并不等价

  initialize、test和increment三个表达式之间用分号分隔,它们各自担当开始化操作、循环条件判断和计数器变量的换代。将它们放在循环的第一行会更易于精晓for循环正在做什么,而且也可以制止遗忘先河化或者递增计数器变量

  initialize说明式只在循环先导从前实施五遍;每一趟循环执行往日会举行test表明式,并判断表明式的结果来控制是否执行循环体,即使test总计结果为真值,则执行循环体中的statement,最终,执行increment表明式

  在for循环的变量开始化表明式中,也得以不拔取var关键字,该变量的开首化可以在表面执行

var count = 10;
var i;
for(i = 0; i < count; i++){
    console.log(i);
}

  由于ECMAScript中不存在块级效率域,因而在循环之中定义的变量也得以在外表访问到

var count = 10;
for(var i = 0; i < count; i++){
    console.log(i);
}
console.log(i);//10

  for循环常见用途是对某个数组里的成套元素举行遍历处理

var beatles = Array('John','Paul','George','Ringo');
for(var count = 0; count < beatles.length; count++){
    alert(beatles[count]);
}

  假如循环中的一遍迭代会改变七个变量,则需要用到逗号运算符,它将初步化表明式和自增表明式合并入一个表明式中以用于for循环

var i,j;
for(i = 0,j =10; i<10; i++,j--) sum+= i*j;

  代码中的循环变量除了是数字外,也可以是其余品类

  可以利用for循环来遍历链表数据结构,并赶回链表中的最后一个目的(也就是第一个不包含next属性的靶子)

function tail(o){
    for(;o.next;o = o.next)/*empty*/;
    return o;
}

  for循环中的initialize、test和increment这多少个表明式中的任何一个都得以忽略,然而两个分行必不可少。倘诺省略test表明式,那么这将是一个死循环。同样,和while(true)类似,死循环的其余一种写法是

for(;;)

【for in语句】

  for/in语句也应用for关键字,但它和健康的for循环是截然不同的一类循环

for(variable in object){
    statement
}

  variable平常是一个变量名,也可以是一个得以生出左值的表明式或一个经过var语句讲明的变量,总而言之必须是一个适用于赋值表达式左边的值。object是一个表达式,这多少个表达式的精打细算结果是一个目标。同样,statement是一个口舌或语句块,它结合了循环的基本点

  for/in循环可以用来更便宜地遍历对象属性成员

for(var p in o){
    console.log(o[p]);
}

  在履行for/in语句的进程中,javascript解释器首先总括object表明式。假如表明式为null或undefined。javascript解释器将会跳过巡回并实施后续的代码。倘若表达式等于一个原始值,那多少个原始值将会转换为与之对应的包装对象(wrapper
object)。否则,expression本身已经是目的了。javascript会依次枚举对象的特性来执行循环。然则,在每一回循环前,javascript都会先总括variable表达式的值,并将属性名(一个字符串)赋值给它

  [注意]比方for/in循环中variable的值可以当做赋值说明式的左值,它可以是擅自表明式,每回循环都会盘算这个表达式,也就是说每回循环它总括的值有可能两样

var obj = {
  x: 1,
  y: 2
};
var props = [];
var i = 0;
for (props[i++] in obj);
props // ['x', 'y']

  javascript数组可是是一种奇特的对象,由此,for/in循环可以像枚举对象属性一样枚举数组索引

var o = {a: 1, b: 2, c: 3};
for (var i in o) {
  console.log(o[i]);
}
// 1
// 2
// 3

  [注意]for/in循环并不会遍历对象的所有属性,只有可枚举(enumerable)的性质才会遍历到

  ECMAScript规范并不曾点名for/in循环按照何种顺序来枚举对象属性。但实则,主流浏览器厂商的javascript实现是遵从性质定义的先后顺序来枚举简单对象的属性,先定义的属性先枚举。假使使用对象直接量的款型成立对象,则将依据直接量中属性的产出顺序枚举。有部分网站和javascript库是借助于那种枚举顺序的,浏览器厂商不大可能会修改这个顺序

 

跳转语句

  跳转语句(jump
statement)可以让解释器跳转到程序的其余部分继续执行,包括break、continue和return语句

【label语句】

  介绍跳转语句不得不涉及标签(label)语句,通过给语句定义标签,就足以在先后的其余地点通过标签名引用这条语句

  标签语句平日与break语句和continue语句配合使用,跳出特定的大循环

identifier: statement

  [注意]用做标签的identifier必须是一个官方的javascript标识符,而不可以是一个保留字

mainloop: while(token != null){
    //Todo
    continue mainloop;
}

  标签的命名空间和变量或函数的命名空间是见仁见智的,因而得以行使同一个标识符作为言语标签和当作变量名或函数名

  语句标签唯有在它所起效果的讲话(当然也足以在它的子句中)内是有定义的。一个讲话标签无法和它里面的口舌标签重名,但在两个代码段不互相嵌套的意况下,是足以出现同名的言辞标签的。带有标签的言辞还足以分包标签,也就是说,任何语句可以有许多个标签

【break语句】

  单独行使break语句的意义是当下退出最内层的轮回或switch语句

break;

for(var i = 0; i < a.length; i++){
    if(a[i] == target) break;
}

  break语句只有出现在循环语句或switch语句中才合法,出现在任何语句中会报错

//报错
if(true){
    break;
}
//报错
function test(){
    var i = 0;
    break;
}
test();

  当希望由此break来跳出非就近的循环体或switch语句时,就会用到带标签的break语句

break labelname;

  当break和标签一块使用时,程序将跳转到这多少个标签所标识的语句块的终结,或者直接终止那么些闭合语句块的实施。当没有任何闭合语句块指定了break所用的竹签,这时会暴发一个语法错误

top:
  for (var i = 0; i < 3; i++){
    for (var j = 0; j < 3; j++){
      if (i === 1 && j === 1) break top;
      console.log( i, j);
    }
  }

  [注意]不管break语句带不带标签,它的控制权都不可以通过函数的境界。比如,对于一条带标签的函数定义语句来说,无法从函数内部通过这一个标签来跳转到函数外部

【continue语句】

  continue语句和break语句相当相近,但它不是脱离循环,而是转而推行下一回巡回

continue;
continue labelname;

  不管continue语句带不带标签,它不得不在循环体内采用。在任何地方使用将会报语法错误

  当执行到continue语句时,当前的大循环逻辑就停下了,随即举行下五回巡回。但在不同档次的循环中,continue行为也大相径庭:

  【1】while循环中,循环起首处指定的exression会重复检测,倘诺检测结果为true,则循环体会从头起头执行

  【2】do
while循环中,程序执行直接跳到循环结尾处,那时会再度判断循环条件,之后才会延续下两回巡回

  【3】for循环中,首先计算自增表明式,然后重新检测test表明式,用以判断是否实施循环体

  【4】在for/in循环中,循环起来遍历下一个属性名,这一个特性名赋给了点名的变量

  [注意]continue语句在while和for循环中的区别:while循环直接进去下一轮的大循环条件判断,但for循环首先总结其increment表明式,然后判断循环条件

//1 3
for(i = 0; i < 5; i++){
    if(i % 2 === 0)continue;
    console.log(i);
}

//1 3 5
var i = 0;
while(i<5){
    i++;    
    if(i % 2 === 0)continue;
    console.log(i);
}

  由于continue在这两种循环中的行为表现不同,由此利用while循环不能完美地模拟等价的for循环

  和break语句看似,带标签的continue语句可以用在嵌套的巡回中,用以跳出多层嵌套的循环体逻辑

top:
  for (var i = 0; i < 3; i++){
    for (var j = 0; j < 3; j++){
      if (i === 1 && j === 1) continue top;
      console.log('i=' + i + ', j=' + j);
    }
  }

【return语句】

  函数调用是一种表明式,而拥有表明式都有值。函数中的return语句就是指定函数调用后的重临值

return expression;

  return语句只可以出现在函数体内,倘若不是会报语法错误。当执行到return语句时,函数终止执行,并重返expression的值给调用程序

function square(x)
{    
    return x*x
};
square(2);

  假如没有return语句,则函数调用仅仅依次执行函数体内的每一条语句直到函数截至,最终回来调用程序。那种情状下,调用表明式的结果是undefined。return语句经常作为函数内的结尾一条语句出现,但并不是说一定要放在函数最终,尽管在履行return语句的时候还有众多继承代码没有履行到,这时函数也依旧会回去调用程序

  return语句可以单独行使而不用带有expression,这样的话也会向调用程序重回undefined

function display_object(o){
    if(!o) return;
}

  在javascript词法结构中,已经涉嫌过分号的用法。所有的跳转语句包括break、continue、return等话语,都不可以在主要字和表达式之间换行,因为javascript会在换行处填补分号

//以及return语句举例,break、continue语句也类似
return
true;

  javascript将其分析为:

return;true;

  而代码的本意是:

return true;

 

参考资料

【1】 ES5/语句 https://www.w3.org/html/ig/zh/wiki/ES5/statements
【2】 阮一峰Javascript标准参照教程——语法概述
http://javascript.ruanyifeng.com/grammar/basic.html#toc12
【3】 W3School-Javascript高级教程——语句
http://www.w3school.com.cn/js/pro_js_statements_if.asp
【4】《javascript权威指南(第6版)》第5章 语句
【5】《javascript高级程序设计(第3版)》第3章 基本概念
【6】《javascript DOM编程艺术(第2版)》第2章 Javascript语法
【7】《javascript语言出色》 第2章 语法