附录 1: 更多(晦涩的)控制结构
¶ 首先是 do
。do
的作用与 while
相似,但它不是执行循环体零次或多次,而是执行一次或多次。do
循环的结构如下所示
do { var answer = prompt("Say 'moo'.", ""); print("You said '", answer, "'."); } while (answer != "moo");
¶ 为了强调条件是在循环运行一次 *之后* 才检查的事实,条件语句被写在了循环体的末尾。
¶ 接下来是 continue
。它与 break
密切相关,并且可以在相同的语句中使用。break
跳出循环,导致程序在循环之后继续执行,而 continue
跳到循环的下一轮迭代。
for (var i = 0; i < 10; i++) { if (i % 3 != 0) continue; print(i, " is divisible by three."); }
¶ 通常可以使用 if
语句来实现类似的效果,但在某些情况下,continue
显得更简洁。
¶ 当一个循环嵌套在另一个循环内时,break
或 continue
语句只会影响内部循环。有时你可能需要跳出 *外部* 循环。为了能够引用特定的循环,循环语句可以进行 标记。标记是一个名称(任何有效的变量名都可以),后面跟着一个冒号 (:
)。
outer: for (var sideA = 1; sideA < 10; sideA++) { inner: for (var sideB = 1; sideB < 10; sideB++) { var hypotenuse = Math.sqrt(sideA * sideA + sideB * sideB); if (hypotenuse % 1 == 0) { print("A right triangle with straight sides of length ", sideA, " and ", sideB, " has a hypotenuse of ", hypotenuse, "."); break outer; } } }
¶ 接下来,有一个称为 switch
的结构,它可以根据某个值来选择要执行的代码。这是一个非常有用的功能,但 JavaScript 使用的语法(源自 C 语言)过于笨拙和丑陋,所以我通常更喜欢使用 if
语句的链。
function weatherAdvice(weather) { switch(weather) { case "rainy": print("Remember to bring an umbrella."); break; case "sunny": print("Dress lightly."); case "cloudy": print("Go outside."); break; default: print("Unknown weather type: ", weather); break; } } weatherAdvice("sunny");
¶ 在 switch
打开的代码块中,你可以编写多个 case
标签。程序将跳转到与 switch
收到的值相对应的标签(使用相当于 ===
的比较方式,所以没有自动类型转换),或者如果未找到匹配的值,则跳转到 default
标签。然后程序开始执行标签处的语句,并 *继续* 执行其他标签后的语句,直到遇到 break
语句。在某些情况下,例如示例中的 "sunny"
case,这可以用于在 case 之间共享部分代码(它建议在晴朗和多云的天气都到户外)。大多数情况下,这只会增加许多丑陋的 break
语句,或者导致你在忘记添加 break
语句时出现问题。
¶ 与循环类似,switch
语句也可以被标记。
¶ 最后,有一个名为 with
的关键字。我从未在实际程序中 *使用* 过它,但我见过其他人使用它,所以了解它是很有用的。使用 with
的代码如下所示
var scope = "outside"; var object = {name: "Ignatius", scope: "inside"}; with(object) { print("Name == ", name, ", scope == ", scope); name = "Raoul"; var newVariable = 49; } show(object.name); show(newVariable);
¶ 在代码块内,传递给 with
的对象的属性充当变量。但是,新引入的变量 *不会* 被添加到该对象的属性中。我认为这个结构背后的想法是,它可能在大量使用对象属性的方法中很有用。你可以用 with(this) {...}
来开始这种方法,之后就不必一直写 this
了。