当前位置: 代码迷 >> 综合 >> 《JavaScript高级程序设计》(第4版)阅读笔记(十八)
  详细解决方案

《JavaScript高级程序设计》(第4版)阅读笔记(十八)

热度:93   发布时间:2024-01-21 18:18:37.0

这一篇继续分享《高程四》第三章的内容。

 

3.6.8 break 和 continue 语句
 

break 和 continue 语句为执行循环代码提供了更严格的控制手段。其中, break 语句用于立即退出循环,强制执行循环后的下一条语句。而 continue 语句也用于立即退出循环,但会再次从循环顶部开始执行(也就是不再继续执行本次循环,但还会执行下次循环)。

下面看一个例子:

let num = 0;
for (let i = 1; i < 10; i++) {if (i % 5 == 0) {break;}num++;
} 
console.log(num); // 4

在上面的代码中, for 循环会将变量 i 由1递增到10。而在循环体内,有一个 if 语句用于检查 i 能否被5整除(使用取模操作符)。如果是,则执行 break 语句,退出循环。变量 num 的初始值为0,表示循环在退出前执行了多少次。当 break 语句执行后,下一执行的代码是 console.log(num) ,显示4。并没有完整地执行10次。之所以循环执行了4次,是因为当 i 等于5时, break 语句会导致循环退出,该次循环不会执行递增 num 的代码。第五次没有完整地执行。

如果将 break 换成 continue ,则会出现不同的效果:

let num = 0;
for (let i = 1; i < 10; i++) {if (i % 5 == 0) {continue;}num++;
} 
console.log(num); // 8

这一次, console.log 显示8,即循环被完整执行了8次。当i 等于5时,循环会在递增 num 之前退出,但会执行下一次迭代,此时 i 是6。然后,循环会一直执行到自然结束,即 i 等于10。最终num 的值是8而不是9,是因为 continue 语句导致它少递增了一次

break 和 continue 都可以与标签语句一起使用,返回代码中特定的位置。这通常是在嵌套循环中,如下面的例子所示:

let num = 0;
outermost:
for (let i = 0; i < 10; i++) {for (let j = 0; j < 10; j++) {if (i == 5 && j == 5) {break outermost;}num++;}
} 
console.log(num); // 55

在这个例子中, outermost 标签标识的是第一个 for 语句。正常情况下,每个循环执行10次,意味着 num++ 语句会执行100次,而循环结束时 console.log 的结果应该是100。但是, break 语句带来了一个变数,即要退出到的标签。添加标签不仅让 break 退出(使用变量 j 的)内部循环,也会退出(使用变量 i )的外部循环。当执行到 i 和 j 都等于5时,循环停止执行,此时 num 的值是55。

continue 语句也可以使用标签,如下面的例子所示:
 

let num = 0;
outermost:for (let i = 0; i < 10; i++) {for (let j = 0; j < 10; j++) {if (i == 5 && j == 5) {continue outermost;}     num++;}
}
console.log(num); // 95

这一次, continue 语句会强制循环继续执行,但不是继续执行内部循环,而是继续执行外部循环。当 i 和 j 都等于5时,会执行 continue ,跳到外部循环继续执行,从而导致内部循环少执行5次(少的是55到59的这5次,接下去直接从60开始了),结果 num 等于95。

组合使用标签语句和 break 、 continue 能实现复杂的逻辑,但也容易出错。注意标签要使用描述性强的文本,而嵌套也不要太深。
 

3.6.9 with 语句
 

with 语句的用途是将代码作用域设置为特定的对象,其语法是:

with (expression) statement;

使用 with 语句的主要场景是针对一个对象反复操作,这时候将代码作用域设置为该对象能提供便利,如下面的例子所示:

let qs = location.search.substring(1);
let hostName = location.hostname;
let url = location.href;

上面代码中的每一行都用到了 location 对象。如果使用with 语句,就可以少写一些代码:

with(location) {let qs = search.substring(1);let hostName = hostname;let url = href;
}

这里, with 语句用于连接 location 对象。这意味着在这个语句内部,每个变量首先会被认为是一个局部变量。如果没有找到该局部变量,则会搜索 location 对象,看它是否有一个同名的属性。如果有,则该变量会被求值为 location 对象的属性。(比如,第一行声明了qs变量,并且用search.substring(1)的结果给它赋值。search就是一个局部变量,没有声明过它,就到location里去找同名的属性,并且给这里的变量search赋值)

严格模式不允许使用 with 语句,否则会抛出错误

警告 由于 with 语句影响性能且难于调试其中的代码,通常不推荐在产品代码中使用 with 语句。

 

3.6.10 switch 语句

 

switch 语句是与 if 语句紧密相关的一种流控制语句,从其他语言借鉴而来。ECMAScript中 switch 语句跟C语言中 switch 语句的语法非常相似,如下所示:

switch (expression) {case value1:statementbreak;case value2:statementbreak;case value3:statementbreak; case value4:statementbreak;default:statement
}

这里的每个 case (条件/分支)相当于:“如果表达式等于后面的值,则执行下面的语句。” break 关键字会导致代码执行跳出switch 语句。如果没有 break ,则代码会继续匹配下一个条件。 default 关键字用于在任何条件都没有满足时指定默认执行的语句(相当于 else 语句)。

有了 switch 语句,开发者就用不着写太多“疯狂嵌套if语句”的代码了。直接用switch来区分每种情况,代码的结构会清晰很多。

为避免不必要的条件判断,最好给每个条件后面都加上 break语句。如果确实需要连续匹配几个条件,那么推荐写个注释表明是故意忽略了 break ,如下所示:

switch (i) {case 25:/*跳过*/case 35:console.log("25 or 35");break;case 45:console.log("45");break;default:console.log("Other");
}

虽然 switch 语句是从其他语言借鉴过来的,但ECMAScript为它赋予了一些独有的特性。首先, switch 语句可以用于所有数据类型(在很多语言中,它只能用于数值),因此可以使用字符串甚至对象。其次,条件的值不需要是常量,也可以是变量或表达式。看下面的例子:

switch ("hello world") {case "hello" + " world":console.log("Greeting was found.");break;case "goodbye":console.log("Closing was found.");break;default:console.log("Unexpected message was found.");
}

这个例子在 switch 语句中使用了字符串。第一个条件实际上使用的是表达式,求值为两个字符串拼接后的结果。因为拼接后的结果等于 switch 的参数,所以 console.log 会输出 "Greeting was found." 。也就是说,作为条件的表达式,只要结果等于switch的参数值,对应case的语句就会执行。
能够在条件判断中使用表达式,就可以在判断中加入更多逻辑:

let num = 25;
switch (true) {case num < 0:console.log("Less than 0.");break;case num >= 0 && num <= 10:console.log("Between 0 and 10.");break;case num > 10 && num <= 20:console.log("Between 10 and 20.");break;default:console.log("More than 20.");
}

上面的代码首先在外部定义了变量 num ,而传给 switch 语的参数之所以是 true ,就是因为每个条件的表达式都会返回布尔值。条件的表达式分别被求值,直到有表达式返回 true ;否则,就会一直跳到 default 语句(这个例子正是如此)。

注意 switch 语句在比较每个条件的值时会使用全等操作符,因此不会强制转换数据类型(比如,字符串 "10" 不等于数值10)。


 

  相关解决方案