51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

带大家了解下 JavaScript 控制流与错误处理

Javascript

JavaScript 支持一套小巧的语句,特别是控制流语句,你可以用它在你的应用程序中实现大量的交互性功能。本章将对这些语句进行概览。

在本章中涉及的语句,JavaScript 参考包含更为详尽的细节。在 JavaScript 代码中,分号(;)字符被用来分割语句。

JavaScript 表达式也是语句。想要了解有关表达式的完整信息,参见表达式与运算符。


块语句 {#块语句}

最基本的语句是用于组合语句的块语句。块由一对花括号界定:


{
  statement1;
  statement2;
  // …
  statementN;
}

示例 {#示例}

块语句通常用于控制流语句(ifforwhile)。

while (x < 10) {
  x++;
}

这里,{ x++; } 就是块语句。

备注:用 var 声明的变量不是块级作用域的,而是函数作用域或脚本作用域的,且设置它们的效果会超越到块本身之外。例如:


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

会输出 2,因为块中 var x 语句和块前面的 var x 语句的作用域是一样的。(在 C 或 Java 中,等效的代码会输出 1。)

使用 letconst 会消除这个作用域效果。

条件语句 {#条件语句}

条件语句是一组会在指定的条件为真时执行的指令。JavaScript 支持两种条件语句:if...elseswitch


if...else 语句 {#if...else_语句}

使用 if 语句在逻辑条件为 true 时执行语句。使用可选的 else 子句在条件为 false 时执行语句。

if 语句看起来像这样:


if (condition) {
  statement1;
} else {
  statement2;
}

这里,condition 可以是任何能求值为 truefalse 的表达式。(想要了解求值为 truefalse 的解释,参见布尔值。)

如果 condition 求值为 true,执行 statement1。否则,执行 statement2statement1statement2 可以是任何的语句,包括继续嵌套的 if 语句。

你也可以使用 else if 组合语句按顺序测试多个条件,就像下面一样:

if (condition1) {
  statement1;
} else if (condition2) {
  statement2;
} else if (conditionN) {
  statementN;
} else {
  statementLast;
}

在多个条件的情况下,只有第一个求值为 true 的逻辑条件才会被执行。想要执行多个语句,将其组合在一个块语句中({ /* ... */ })。

最佳实践 {#最佳实践}

一般而言,总是使用块语句是最佳实践------特别是嵌套 if 语句的时候:

if (condition) {
  // condition 为真时的语句
  // …
} else {
  // condition 为假时的语句
  // …
}

一般而言,最好不要将赋值(例如,x = y)作为 if...else 的条件:


if (x = y) {
  // 在这里添加语句
}

然而,在极少数情况下,你会发现自己想要这么做,while 文档中的使用赋值作为条件小节是你应该了解并遵循的通用的最佳实践语法指南。

假值 {#假值}

下面这些值求值为 false(也叫做假值):

  • false

  • undefined

  • null

  • 0

  • NaN

  • 空字符串(""

所有其他的值------包括所有的对象------在被传递给条件语句时会求值为 true

示例 {#示例_2}

在下列示例中,如果 Text 对象中的字符数为 3,函数 checkData 将返回 true;否则,显示警告并返回 false

function checkData() {
  if (document.form1.threeChar.value.length === 3) {
    return true;
  } else {
    alert(`请正好输入 3 个字符。${document.form1.threeChar.value}是无效的`);
    return false;
  }
}

switch 语句 {#switch_语句}

switch 语句允许程序求一个表达式的值并且尝试将表达式的值和 case 标签进行匹配。如果匹配成功,程序会执行相关的语句。

switch 语句看起来像这样:

switch (expression) {
  case label1:
    statements1;
    break;
  case label2:
    statements2;
    break;
  // …
  default:
    statementsDefault;
}

JavaScript 求值上面的 switch 语句的过程如下:

  • 程序首先查找一个与 expression 的值匹配的 case 子句标签,然后将控制权转移到该子句,执行相关的语句。

  • 如果没有匹配的标签,程序会去找可选的 default 子句:

    • 如果找到了 default 子句,程序会将控制权转移到该子句,执行相关的语句。

    • 如果没有找到 default 子句,程序会继续执行 switch 语句后面的语句。

    • default 子句通常是最后一个子句,当然这不是必须的。)

break 语句 {#break_语句}

每个 case 子句会关联一个可选的 break 语句,它能保证在匹配的语句被执行后程序可以跳出 switch 并且继续执行 switch 后面的语句。如果 break 被忽略,程序会在 switch 语句内继续执行(将会执行下一个 case 的语句,依此类推)。

示例 {#示例_3}

在下列示例中,如果 fruitType 等于 "Bananas",程序将该值与 case "Bananas" 匹配,并执行相关语句。当执行到 break 时,程序结束 switch 并执行 switch 后面的语句。如果不写 break ,那么程序将会执行 case "Cherries" 下的语句。

switch (fruitType) {
  case "Oranges":
    console.log("橙子是 $0.59 一磅");
    break;
  case "Apples":
    console.log("苹果是 $0.32 一磅");
    break;
  case "Bananas":
    console.log("香蕉是 $0.48 一磅");
    break;
  case "Cherries":
    console.log("樱桃是 $3.00 一磅");
    break;
  case "Mangoes":
    console.log("芒果是 $0.56 一磅。");
    break;
  case "Papayas":
    console.log("木瓜是 $2.79 一磅。");
    break;
  default:
    console.log(`对不起,${fruitType} 卖完了。`);
}
console.log("还有其他什么是你喜欢的吗?");

异常处理语句 {#异常处理语句}

你可以用 throw 语句抛出一个异常并且用 try...catch 语句处理它。

  • throw 语句

  • try...catch 语句

异常类型 {#异常类型}

JavaScript 可以抛出任意对象。然而,并非所有抛出的对象都是生而平等的。尽管抛出数字或者字符串作为错误信息十分常见,但是用下列其中一种专门为这个目的而创建的异常类型通常更为高效:

  • ECMAScript 异常

  • DOMException

throw 语句 {#throw_语句}

使用 throw 语句抛出异常。throw 语句会指明要抛出的值:


throw expression;

你可以抛出任意表达式而不是特定类型的表达式。下面的代码抛出了几个不同类型的异常:

throw "错误 2"; // 字符串类型
throw 42; // 数字类型
throw true; // 布尔类型
throw {
  toString() {
    return "我是一个对象";
  },
};

try...catch 语句

try...catch 语句用于标记一段要尝试的语句块,并指定抛出异常时的一个或多个响应。如果抛出了异常,try...catch 语句会捕获它。

try...catch 语句由 try 块(其包含一个或多个语句)和 catch 块(其包含在 try 块中抛出异常时要执行的语句)组成。

换句话说,你希望 try 块执行成功------但如果它没有执行成功,那么你希望将控制转移到 catch 块。如果 try 块中的语句(或者在 try 块中调用的函数里)抛出了异常,那么控制立马转移到 catch 块。如果 try 块没有抛出异常,catch 块就会被跳过。finally 块总会紧跟在 trycatch 块之后执行,但会在 try...catch 语句后面的语句之前执行。

下列示例使用了 try...catch 语句。示例调用的函数是根据传递的值从数组中获取一个月份名称。如果该值与月份数值(1-12)不相符,会抛出带有 "无效的月份数值" 值的异常,然后在 catch 块的语句中设 monthName 变量为 "未知"

function getMonthName(mo) {
  mo--; // 将月份调整为数组索引(这样的话,0 = 一月,11 = 十二月)
  const months = [
    "一月", "二月", "三月", "四月", "五月", "六月",
    "七月", "八月", "九月", "十月", "十一月", "十二月",
  ];
  if (months[mo]) {
    return months[mo];
  } else {
    throw new Error("无效的月份数值"); // 在这使用 throw 关键字
  }
}

try {
  // 要尝试的语句
  monthName = getMonthName(myMonth); // 可能抛出异常的函数
} catch (e) {
  monthName = "未知";
  logMyErrors(e); // 将异常对象传递给错误处理器(例如,你写的函数)
}

catch 块

你可以使用 catch 块来处理所有可能在 try 块中产生的异常。

catch (exception) {
  statements
}

catch 块指定的标识符(上述语句中的 exception)会存储由 throw 语句指定的值。你可以用这个标识符来获取抛出的异常的信息。在进入 catch 块时 JavaScript 会创建这个标识符。标识符只存在于 catch 块的存续期间里。当 catch 块执行完成时,标识符不再可用。

举个例子,下面代码抛出了一个异常。当异常出现时控制会转移到 catch 块。

try {
  throw "我的异常"; // 生成一个异常
} catch (err) {
  // 处理异常的表达式
  logMyErrors(err); // 将异常对象传递给错误处理器
}

赞(1)
未经允许不得转载:工具盒子 » 带大家了解下 JavaScript 控制流与错误处理