JavaScript设计程序结构

JavaScript提供了20多个命令,分别执行不同的操作。从用途分析,这些命令可以分为:声明语句、分支控制、循环控制、流程控制、异常处理和其他语句。本贴将重点讲解程序结构设计命令,包括if条件判断语句、switch多分支语句、for循环语句、while循环语句、do/while循环语句、break中断语句、continue继续执行语句等。

1、分支结构

1.1、if语句

if语句允许根据特定的条件执行指定的语句,语法格式如下:

    if (expr)
        statement

如果表达式expr的值为真,则执行语句statement;否则,将忽略语句statement。

【示例】使用内置函数Math.random()随机生成一个1~100的整数,然后判断该整数能否被2整除,如果可以整除,则输出显示:

    var num = parseInt( Math.random()*99 + 1 ); //使用random()函数生成一个随机数
    if ( num % 2 == 0){                         //判断变量num是否为偶数
        console.log( num + "是偶数。");
    }

提示:如果statement为单句,可以省略大括号,例如:

    if ( num % 2 == 0)
       console.log( num + "是偶数。");

1.2、else语句

else语句仅在if或elseif语句的条件表达式为假的时候执行,语法格式如下:

    if (expr)
        statement1
    else
        statement2

如果表达式expr的值为真,则执行语句statement1;否则,将执行语句statement2。其流程控制如下图所示:

    var num = parseInt( Math.random()*99 + 1 );                  //使用random()函数生成一个随机数
    if ( num % 2 == 0){                                          //判断变量num是否为偶数
        console.log( num + "是偶数。");
    } else {
        console.log( num + "是奇数。");
    }

1.3、switch语句

switch语句专门用来设计多分支条件结构。与if else多分支结构相比,switch结构更简洁,执行效率更高。语法格式如下:

    switch (expr){
        case value1:
            statementList1
            break;
        case value2:
            statementList2
            break;case valuen:
            statementListn
            break;
        default:
            default statementList
    }

switch语句根据表达式expr的值,依次与case后面表达式的值进行比较。如果相等,则执行其后的语句段,只有遇到break语句或者switch语句结束才终止;如果不相等,继续查找下一个case。switch语句包含一个可选的default语句,如果在前面的case中没有找到相等的条件,则执行default语句,它与else语句类似。switch语句流程控制如下图所示:
JavaScript设计程序结构_第1张图片

1.4、default语句

default是switch的子句,可以位于switch内的任意位置,不会影响多重分支的正常执行。下面结合示例介绍使用default语句应该注意的3个问题。

提示:如果default下面还有case子句,应该在default后面添加break语句,终止switch结构,防止程序突破case条件的限制继续执行下面的case子句。

【示例】使用switch语句设计一个四则运算函数。在switch结构内,先使用case枚举4种可预知的算术运算,当然还可以继续扩展case子句,枚举所有可能的操作,但是无法枚举所有不测,因此最后使用default处理意外情况。
JavaScript设计程序结构_第2张图片
提示:default语句与case语句简单比较如下:

  • 语义:default为默认项,case为判例。
  • 功能扩展:default选项是唯一的,不可以扩展;而case选项是可以扩展的,没有限制。
  • 异常处理:default与case扮演的角色不同,case用于枚举,default用于异常处理。

2、循环结构

2.1、while语句

while语句是最基本的循环结构,语法格式如下:

    while (expr)
        statement

当表达式expr的值为真时,将执行statement语句,执行结束后,再返回到expr表达式继续进行判断。直到表达式的值为假,才跳出循环,执行下面的语句。while循环语句的流程控制如下图所示:
JavaScript设计程序结构_第3张图片
【示例】使用while语句输出1~100的偶数:

    var n = 1;                                   //声明并初始化循环变量
    while(n <= 100){                             //循环条件
        n ++ ;                                   //递增循环变量
        if( n%2 == 0) document.write( n + " " ); //执行循环操作
    }

2.2、do…while语句

do…while与while循环相似,区别在于表达式的值是在每次循环结束时检查,而不是在开始时检查。因此,do…while循环能够保证至少执行一次循环,而while循环就不一定了。如果表达式的值为假,则直接终止循环,不进入循环。语法格式如下:

    do
        statement
    while (expr)

do…while循环语句的流程控制如下图所示:
JavaScript设计程序结构_第4张图片
提示:建议在do…while结构的尾部使用分号表示语句结束,以避免意外情况发生。

2.3、for语句

for语句的结构是一种更简洁的循环结构,语法格式如下:

    for (expr1; expr2; expr3)
        statement

其中,表达式expr1在循环开始前无条件地求值一次,而表达式expr2在每次循环开始前求值。如果表达式expr2的值为真,则执行循环语句,否则将终止循环,执行下面代码。表达式expr3在每次循环之后被求值。for循环语句的流程控制如下图所示:
JavaScript设计程序结构_第5张图片
【示例】使用嵌套循环求1~100的所有素数。外层for循环遍历每个数字,在内层for循环中,使用当前数字与其前面的数字求余。如果有至少一个能够被整除,则说明它不是素数;如果没有一个被整除,则说明它是素数,最后输出当前数字:

    for(var i=2 ; i<100 ; i++){//打印2~100的素数
        var b = true;
        for(var j = 2; j < i; j++){
            //判断i能否被j整除,能被整除则说明不是素数,修改布尔值为false
            if(i%j == 0)  b = false ;
        }
        if(b)  document.writeln(i + " ");               //打印素数
    }

2.4、for…in语句

for…in语句是for语句的一种特殊形式,语法格式如下:

    for ( [var] variable in <object | array> )
        statement

variable表示一个变量,可以在其前面附加var语句,用来直接声明变量名。in后面是一个对象或数组类型的表达式。在遍历对象或数组过程中,把获取的每一个值赋值给variable。

然后,执行statement语句,其中可以访问variable读取每个对象属性或数组元素的值。执行完毕,返回继续枚举下一个元素,周而复始,直到所有元素都被枚举为止。

注意:对于数组来说,值是数组元素的下标;对于对象来说,值是对象的属性名或方法名。

【示例1】使用for…in语句遍历数组,并枚举每个元素及其值:

    var a = [1, true, "0", [false], {}];                        //声明并初始化数组变量
    for(var n in a){                                            //遍历数组
        document.write( "a[" + n + "] = " + a[n] + "
"
); //显示每个元素及其值 }

3、流程控制

3.1、label语句

在JavaScript中,使用label语句可以为一行语句添加标签,以便在复杂结构中设置跳转目标。语法格式如下:

    label : statements

label为任意合法的标识符,但不能使用保留字。使用冒号分隔标签名与标签语句。

注意:由于标签名与变量名属于不同的命名体系,所以标签名与变量名可以重复。但是,标签名与属性名语法相似就不能重名。例如,下面写法是错误的:

    a:{                         //标签名
        a:true                  //属性名
    }

使用点语法、中括号语法可以访问属性,但是无法访问标签语句:

    console.log(o.a);              //可以访问属性
    console.log(b.a);              //不能访问标签语句,将抛出异常

label与break语句配合使用,主要应用在循环结构、多分支结构中,以便跳出内层嵌套体。

3.2、break语句

break语句能够结束当前for、for/in、while、do/while或者switch语句的执行。同时,break语句可以接收一个可选的标签名决定跳出的结构语句。语法格式如下:

    break label;

如果没有设置标签名,则表示跳出当前最内层结构。break语句流程控制如下图:
JavaScript设计程序结构_第6张图片
【示例1】在客户端查找document的bgColor属性。由于完全遍历document对象会浪费时间,因此设计一个条件,判断所枚举的属性名是否等于bgColor。如果相等,则使用break语句跳出循环:

    for(i in document){
        if(i.toString() == "bgColor"){
            document.write("document." + i + "=" + document[i] +
"
"
); break; } }

在上面代码中,break语句并非跳出当前的if结构体,而是跳出当前最内层的循环结构。

【示例2】在嵌套结构中,break语句并没有跳出for/in结构,仅仅退出switch结构:

    for(i in document){
        switch(i.toString()){
            case "bgColor":
                document.write("document." + i + "=" + document[i] + "
"
); break; default: document.write("没有找到"); } }

【示例3】针对示例2,可以为for…in语句定义一个标签outloop,然后在最内层的break语句中设置该标签名,这样当条件满足时就可以跳出最外层的for…in循环结构:

    outloop:for(i in document){
        switch(i.toString()){
            case "bgColor":
                document.write("document." + i + "=" + document[i] + "
"
); break outloop; default: document.write("没有找到"); } }

注意:break语句和label语句配合使用仅限于嵌套的循环结构,或者嵌套的switch结构,且需要退出非当前层结构时。break与标签名之间不能够包含换行符,否则JavaScript会解析为两个句子。

break语句的主要功能是提前结束循环或多重分支,主要用在无法预控的环境下,避免死循环或者空循环。

3.3、continue语句

continue语句用在循环结构内,用于跳过本次循环中剩余的代码,并在表达式的值为真时,继续执行下一次循环。它可以接收一个可选的标签名,来决定跳出的循环语句。语法格式如下:

    continue label;

4、异常处理

4.1、try/catch/finally语句

try/catch/finally是JavaScript异常处理语句,语法格式如下:

    try{
        //调试代码块
    }
    catch(e){
        //捕获异常,并进行异常处理的代码块
    }
    finally{
        //后期清理代码块
    }

在正常情况下,JavaScript按顺序执行try子句中的代码。如果没有异常发生,则会忽略catch子句,跳转到finally子句中继续执行。

如果在try子句中运行时发生错误,或者使用throw语句主动抛出异常,则执行catch子句中的代码,同时传入一个参数,引用Error对象。

注意:在异常处理结构中,大括号不能够省略。

【示例1】先在try子句中制造一个语法错误,然后在catch子句中获取Error对象,读取错误信息,最后在finally子句中提示代码:

    try{
        1=1;                                         //非法语句
    }
    catch(error){                                    //捕获错误
        console.log(error.name);                     //访问错误类型
        console.log(error.message);                  //访问错误详细信息
    }
    finally{                                         //清除处理
      console.log("1=1");                            //提示代码
    }

catch和finally子句是可选的。在正常情况下,应该包含try和catch子句。

    try{ 1=1; }
    catch(error){}

注意:不管try语句是否完全执行,finally语句最后都必须执行。即使使用跳转语句跳出了异常处理结构,也必须在跳出之前先执行finally子句。

【示例2】在函数体内设计一个异常处理结构,为每个子句添加一个return语句。调用函数后,实际返回的是“finally”,而不是“try”,因为finally子句必须最后执行。如果把finally子句去掉,函数才会返回“try”:

    function test(){
        try{
            return "try";
        }catch(error){
            return "catch";
        }finally{
            return "finally";
        }
    }
    console.log( test());               //返回"finally"

try/catch/finally语句允许嵌套使用,嵌套的层数不限,同时形成一条词法作用域链。在try中发生异常时,JavaScript会停止程序的正常执行,并跳转到层级最近的catch子句(异常处理器)。如果没有找到异常处理器,则会沿着作用域链,检查上一级的catch子句,以此类推,直到找到一个异常处理器为止。如果在程序中没有找到任何异常处理器,将会显示错误。

4.2、throw语句

throw语句能够主动抛出一个异常,语法格式如下:

    throw expression;

expression是任意类型的表达式,一般为Error对象,或者Error子类实例。

当执行throw语句时,程序会立即停止执行。只有当使用try/catch语句捕获到被抛出的值时,程序才会继续执行。

【示例】在循环体内设计当循环变量大于5时,定义并抛出一个异常:

    try{
        for(var i=0; i<10;i++){
            if(i>5) throw new Error("循环变量的值大于5了");    //定义错误对象,并抛出异常
            console.log(i);
        }
    }
    catch(error){ }                                           // 捕获错误,其中error就是new Error()的实例

在抛出异常时,JavaScript也会停止程序的正常执行,并跳转到最近的catch子句。如果没有找到catch子句,则会检查上一级的catch子句,以此类推,直到找到一个异常处理器为止。如果在程序中没有找到任何异常处理器,将会显示错误。

你可能感兴趣的:(Web,#,JavaScript,javascript,前端,开发语言)