流程控制与错误处理

流程控制

在JavaScript中,分号;用于分割代码中的语句,任何表达式(expression)也是语句(statement)。

语句块

最基本的语句是块语句,用于对语句进行分组,该块有一对大括号{}进行定界:

1
2
3
4
{
语句1;
语句2;
}

语句块通常和流程控制语句(ifforwhile)一起使用,例如:

1
2
3
if(x < 10) {
console.log(x++);
}

在ES6之前,JavaScript没有块级作用域,在块中引入的变量的作用域是包含函数或者脚本,并且设置他们的效果将持续到块本身之外,如:

1
2
3
4
5
var x = 1;
{
var x = 2;
}
console.log(x); // 2

在ES6之后,可以使用letconst声明块级作用域变量。

条件语句

条件语句是一组在指定条件为true时执行的语句,JavaScript支持两个条件语句:if...elseswitch

  • if...else语句

    如果条件为真,则使用if语句执行一条语句,如果条件为假,则使用可选的else子句执行一条语句。语法如下:

    1
    2
    3
    4
    5
    if(条件) {
    语句1;
    } else {
    语句2;
    }

    这里的条件可以是任何计算结果为布尔值的表达式,如果结果为true则执行语句1,如果条件为false则执行语句2,语句1和语句2可以是任何语句,包括进一步嵌套if语句。JavaScript中的else ifelse语句和if语句嵌套的结果。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (条件1) {
    语句1;
    } else if (条件2) {
    语句2;
    } else if (条件3) {
    语句3;
    } else {
    语句4;
    }

    如果需要在条件表达式中使用赋值,通常的做法是在赋值周围加上其他括号,如:

    1
    2
    3
    if((x = y)) {
    语句;
    }

    Boolean转换为false的值:

    • false
    • undefined
    • null
    • 0
    • NaN
    • 空字符串" "

    其他值包括所有对象都或被转为true。注意原始的布尔类型和布尔对象的区别:

    1
    2
    3
    var b = new Boolean(false);
    if(b) // => true,b是一个对象
    if(b === true) // => false
  • switch语句

    switch语句允许一个程序求一个表达式的值并且尝试去匹配表达式的值到一个case标签,如果匹配成功,则执行相关语句:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    switch (expression) {
    case label_1:
    statements_1
    [break;]
    case label_2:
    statements_2
    [break;]

    default:
    statements_def
    [break;]
    }

    程序会首先查找一个与expression匹配的case语句,然后将控制权转移到该子句并执行相关的语句。如果没有匹配值,则程序会去查找default字句,如果找到了default字句则执行相关的语句,如果没有找到,程序会执行switch后面的语句,default语句通常出现在switch语句的最后面,当然这不是必须的。

    每个case语句会关联一个可选的break语句,保证在匹配的语句被执行完成后可以跳出switch语句并继续执行后面的语句,如果break被忽略,则程序将继续执行switch语句中的下一个case语句

异常处理

在JavaScript中可以使用throw语句引发异常,并使用try...catch语句捕获处理它。

异常类型

JavaScript可以抛出任意对象作为异常,但不是所有对象都能产生相同结果。尽管抛出数字或字符串作为异常信息非常常见,但是用下列其中一种异常类型来创建将更加高效:

  • ECMAScript exceptions
  • DOMException and DOMError

throw语句

使用throw语句引发异常,并制定要抛出的异常的值:

1
throw 'Error'

try...catch语句

try...catch语句标记一块待尝试的语句,并制定一个或多个引发异常的响应,如果引发一个异常,那么就可以使用try...catch语句捕获它。

try...catch语句包含一个try代码块,可以有一个或多个语句。零个或一个catch代码块,包含try语句块中引发异常时需要执行的语句。如果try中的代码块没有抛出异常,则catch代码块被跳过。finally代码块总会在trycatch代码块之后执行。

  • catch代码块:
1
2
3
catch (catchID) {
statements
}

catch块指定了一个标识符(catchID)来存放抛出语句指定的值,可以用这个标识符来获取抛出的异常信息。在插入trrow块中创建这个标识符,标识符只存在与catch块的存续期间内,当catch块执行完成时,标识符不在可用。

  • finally代码块

    finally语句块无论是否抛出异常都会执行,如果抛出了一个异常,就算没有异常处理也会执行。如果finally块返回一个值,则这个值将会成为整个try...catch...finally流程的返回值,不管在trycatch中是否有任何的return语句。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function foo() {
    try{
    return 0;
    }catch (err) {

    }finally {
    console.log('finally');
    }
    }
    console.log(foo()); // 0

    try或者catch里使用return语句,其会作为整个try...catch...finally流程的返回值,而不会中断流程的执行。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function foo(){
    try{
    return 0;
    } catch(err) {

    } finally {
    return 1;
    }
    }
    console.log(foo()); // 1

    如果在finally块中有定义return,则会覆盖其他的返回值。

  • 使用Error对象

    根据错误类型,可以使用namemessage获取更精炼的信息。name提供了常规的错误类(如DOMExceptionError),message提供了一条从错误对象转换成从字符串的简明信息。如果要抛出自己的异常,可以利用这些属性,使用Error的构造函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function doSomethingErrorProne() {
    if (ourCodeMakesAMistake()) {
    throw (new Error('The message'));
    } else {
    doSomethingToGetAJavascriptError();
    }
    }
    try {
    doSomethingErrorProne();
    } catch (e) {
    console.error(e.name); // 'Error'
    console.error(e.message); // 'The message', or a JavaScript error message
    }

本文参考资料

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

扫一扫,分享到微信

微信分享二维码
  • © 2019-2021 musi

请我喝杯咖啡吧~

支付宝
微信