JavaScript 支持一套小巧的语句,特别是控制流语句,你可以用它在你的应用程序中实现大量的交互性功能。本章将对这些语句进行概览。
在本章中涉及的语句,JavaScript 参考包含更为详尽的细节。在 JavaScript 代码中,分号(;
)字符被用来分割语句。
JavaScript 表达式也是语句。想要了解有关表达式的完整信息,参见表达式与运算符。
块语句 {#块语句}
最基本的语句是用于组合语句的块语句。块由一对花括号界定:
{
statement1;
statement2;
// …
statementN;
}
示例 {#示例}
块语句通常用于控制流语句(if
、for
、while
)。
while (x < 10) {
x++;
}
这里,{ x++; }
就是块语句。
备注:用 var
声明的变量不是块级作用域的,而是函数作用域或脚本作用域的,且设置它们的效果会超越到块本身之外。例如:
var x = 1;
{
var x = 2;
}
console.log(x); // 2
会输出 2
,因为块中 var x
语句和块前面的 var x
语句的作用域是一样的。(在 C 或 Java 中,等效的代码会输出 1
。)
使用 let
或 const
会消除这个作用域效果。
条件语句 {#条件语句}
条件语句是一组会在指定的条件为真时执行的指令。JavaScript 支持两种条件语句:if...else
和 switch
。
if...else 语句 {#if...else_语句}
使用 if
语句在逻辑条件为 true
时执行语句。使用可选的 else
子句在条件为 false
时执行语句。
if
语句看起来像这样:
if (condition) {
statement1;
} else {
statement2;
}
这里,condition
可以是任何能求值为 true
或 false
的表达式。(想要了解求值为 true
和 false
的解释,参见布尔值。)
如果 condition
求值为 true
,执行 statement1
。否则,执行 statement2
。statement1
和 statement2
可以是任何的语句,包括继续嵌套的 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
块总会紧跟在 try
和 catch
块之后执行,但会在 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); // 将异常对象传递给错误处理器
}