关于javascript:JavaScript-系列四流程控制

32次阅读

共计 7993 个字符,预计需要花费 20 分钟才能阅读完成。

“Code tailor”,为前端开发者提供技术相干资讯以及系列根底文章,微信关注“小和山的菜鸟们”公众号,及时获取最新文章。

前言

在开始学习之前,咱们想要告诉您的是,本文章是对 JavaScript 语言常识中 “ 流程管制 ” 局部的总结,如果您已把握上面常识事项,则可跳过此环节间接进入题目练习

  • if 语句
  • while、do-while 语句
  • for 语句、for-in 语句、for-of 语句
  • break 语句和 continue 语句
  • switch 语句
  • try/catch 语句

汇总总结

ECMA-262 形容了一些语句(也称为流控制语句),而 ECMAScript 中的大部分语法都体现在语句中。语句通常应用一或多个关键字实现既定的工作。语句能够简略,也能够简单。简略的如通知函数退出,简单的如列出一堆要反复执行的指令。

if 语句

if 语句是应用最频繁的语句之一,语法如下:

if (condition) {statement1} else {statement2}

这里的条件 (condition) 能够是任何表达式,并且求值后果不肯定是布尔值。ECMAScript 会主动调用 Boolean() 函数将这个表达式的值转换为布尔值。如果条件求值为 true,则执行语句 statement1; 如果条件求值为 false,则执行语句 statement2。这里的语句可能是一行代码,也可能是一个代码块(即蕴含在一对花括号中的多行代码)如下列代码:

if (xhs > 1) {console.log('xhs 满足大于 1!')
} else {console.log('xhs 不满足大于 1!')
}

下面代码当 xhs 满足大于 1 时,输入 xhs 满足大于 1!,当 xhs 不满足大于 1 时,输入 xhs 不满足大于 1!

能够像这样间断应用多个 if 语句:

if (condition1) {statement1} else if (condition2) {statement2} else {statement3}

上面是一个例子:

if (xhs > 25) {console.log('xhs 满足大于 25')
} else if (xhs < 0) {console.log('xhs 满足小于 0')
} else {console.log('xhs 在 0 到 25 之间')
}

do-while 语句

do-while 语句是一种后测试循环语句,即循环体中的代码执行后才会对退出条件进行求值。换句话说,循环体内的代码至多执行一次do-while 的语法如下:

do {statement} while (expression)

上面是一个例子:

let xhs = 0
do {xhs += 2} while (xhs < 10)

在下面的例子中,变量 xhs 先加了 2,而后用 2 去与10 做比拟,如果小于 10,循环就会反复执行,直到 xhs >= 10

留神 后测试循环常常用于这种情景: 循环体内代码在退出前至多要执行一次。

while 语句

while 语句是一种先测试循环语句,即先检测退出条件,再执行循环体内的代码。因而,while 循环体内的代码有可能不会执行。上面是 while 循环的语法:

while (expression) {statement}

这是一个例子:

let i = 0
while (i < 10) {i += 2}

在这个例子中,变量 xhs0 开始,每次循环递增 2。只有 xhs 小于 10,循环就会持续。

for 语句

for 语句也是先测试语句,只不过减少了进入循环之前的初始化代码(initialization),以及循环执行后要执行的表达式(loop-expression),语法如下:

for (initialization; expression; loop - expression) {statement}

上面是一个用例:

let xhsLength = 10for (let xhs = 0; xhs < xhsLength; xhs++) {console.log(xhs)}

以上代码在循环开始前定义了变量 xhs 的初始值为 0。而后求值条件表达式,如果求值后果为 true (xhs < xhsLength),则执行循环体。因而循环体也可能不会被执行。如果循环体被执行了,则循环后表达式也会执行,以便递增变量 xhsfor 循环跟上面的 while 循环是一样的:

let xhsLength = 10let xhs = 0while (xhs < xhsLength) {console.log(xhs)  xhs++}

无奈通过 while 循环实现的逻辑,同样也无奈应用 for 循环实现。因而 for 循环只是将循环相干的代码封装在了一起而已。

for 循环的初始化代码中,其实是能够不应用变量申明关键字的。不过,初始化定义的迭代器变 量在循环执行实现后简直不可能再用到了。因而,最清晰的写法是应用 let 申明迭代器变量,这样就能够将这个变量的作用域限定在循环中。

初始化、条件表达式和循环后表达式都不是必须的。因而,上面这种写法能够创立一个无穷循环:

for (;;) {// 无穷循环  doSomething()}

如果只蕴含条件表达式,那么 for 循环实际上就变成了 while 循环:

let xhsLength = 10let xhs = 0for (; xhs < xhsLength;) {console.log(xhs)  xhs++}

这种多功能性使得 for 语句在这门语言中应用十分宽泛。

for-in 语句

for-in 语句是一种严格的迭代语句,用于枚举对象中的非符号键属性,语法如下:

for (property in expression) {statement}

上面是一个例子:

for (const xhsName in object) {console.log(xhsName)}

这个例子应用 for-in 循环显示了对象 object 的所有属性。每次执行循环,都会给变量 xhsName 赋予一个 object 对象的属性作为值,直到 object 的所有属性都被枚举一遍。与 for 循环 一样,这里管制语句中的 const 也不是必须的。但为了确保这个局部变量不被批改,举荐应用 const

ECMAScript 中对象的属性是无序的,因而 for-in 语句不能保障返回对象属性的程序。换句话说, 所有可枚举的属性都会返回一次,但返回的程序可能会因浏览器而异。

如果 for-in 循环要迭代的变量是 null undefined,则不执行循环体。

for-of 语句

for-of 语句是一种严格的迭代语句,用于遍历可迭代对象的元素,语法如下:

也就是说只有原型对象实现了 @@iterator 办法,该对象即可被for-of

for (property of expression) {statement}

上面是示例:

for (const xhsName of [2, 4, 6, 8]) {console.log(xhsName) // 别离打印 2,4,6,8}

在这个例子中,咱们应用 for-of 语句显示了一个蕴含 4 个元素的数组中的所有元素。循环会始终继续到将所有元素都迭代完。与 for 循环一样,这里管制语句中的 const 也不是必须的。但为了确保这个局部变量不被批改,举荐应用 const

for-of 循环会依照可迭代对象的 next() 办法产生值的程序迭代元素。对于可迭代对象,请详见 ES6 系列的 Iterator 篇。

如果尝试迭代的变量不反对迭代,则 for-of 语句会抛出谬误。

break 和 continue 语句

breakcontinue 语句为执行循环代码提供了更严格的管制伎俩。其中,break 语句用于立刻退出循环,强制执行循环后的下一条语句。而 continue 语句也用于立刻退出循环,但会再次从循环顶部开始执行。上面看一个例子:

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

在下面的代码中,for 循环会将变量 xhs1 递增到 10。而在循环体内,有一个 if 语句用于查看 xhs 是否被整除 (应用取模操作符)。如果是,则执行 break 语句,退出循环。变量 xhsNumber 的初始值为 0,示意循环在退出前执行了多少次。当 break 语句执行后,下一行执行的代码是 console.log(num),显示 4。之所以循环执行了 4 次,是因为当 xhs 等于 5 时,break 语句会导致循环退出,该次循环不会执行递增 xhsNumber 的代码。如果将 break 换成 continue,则会呈现不同的成果:

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

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

breakcontinue 都能够与标签语句一起应用,返回代码中特定的地位。这通常是在嵌套循环中,如上面的例子所示:

let xhsNumber = 0xhsRookies: for (let xhs = 0; xhs < 10; xhs++) {for (let xhsJJ = 0; xhsJJ < 10; xhsJJ++) {if (xhs == 5 && xhsJJ == 5) {break xhsRookies}    xhsNumber++  }}console.log(xhsNumber) // 55

在这个例子中,xhsRookies 标签标识的是第一个 for 语句。失常状况下,每个循环执行 10 次,意味着 xhsNumber++ 语句会执行 100 次,而循环完结时 console.log 的后果应该是 100。然而,break 语句带来了一个变数,即要退出到的标签。增加标签不仅让 break 退出外部循环,也会退出内部循环。当执行到 xhsxhsJJ 都等于 5 时,循环进行执行,此时 xhsNumber 的值是 55continue 语句也能够应用标签,如上面的例子所示:

let xhsNumber = 0xhsRookies: for (let xhs = 0; xhs < 10; xhs++) {for (let xhsJJ = 0; xhsJJ < 10; xhsJJ++) {if (xhs == 5 && xhsJJ == 5) {continue xhsRookies}    xhsNumber++  }}console.log(xhsNumber) // 95

这一次,continue 语句会强制循环继续执行,但不是继续执行外部循环,而是继续执行内部循环。当 xhsxhsJJ 都等于 5 时,会执行 continue,跳到内部循环继续执行,从而导致外部循环少执行 5 次,结 果 xhsNumber 等于 95

组合应用标签语句和 breakcontinue 能实现简单的逻辑,但也容易出错。留神标签要应用描述性强的文本,而嵌套也不要太深。

switch 语句

switch 语句是与 if 语句严密相干的一种流控制语句,如下所示:

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

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

有了 switch 语句,开发者就用不着写相似这样的代码了:

if (xhs == 25) {console.log('25')} else if (xhs == 35) {console.log('35')} else if (xhs == 45) {console.log('45')} else {console.log('xhsRookies')}

而是能够这样写:

switch (xhs) {case 25:    console.log('25')    break  case 35:    console.log('35')    break  case 45:    console.log('45')    break  default:    console.log('xhsRookies')}

为防止不必要的条件判断,最好给每个条件前面都加上 break 语句。如果的确须要间断匹配几个条件,那么举荐写个正文表明是成心疏忽了 break,如下所示:

switch (xhs) {case 25:    console.log('25')  /* 跳过 */  case 35:    console.log('25 or 35')    break  case 45:    console.log('45')    break  default:    console.log('xhsRookies')}

ECMAScriptswitch 赋予了一些独有的个性。首先,switch 语句能够用于所有数据类型(在很多语言中,它只能用于数值),因而能够应用字符串甚至对象。其次,条件的值不须要是常量,也能够是变量或表达式。看上面的例子:

switch ('hello xhsRookies') {case 'hello' + 'xhsRookies':    console.log('hello,xhs-rookies')    break  case 'goodbye':    console.log('goodbye,xhs-rookies')    break  default:    console.log('sorry,xhs-rookies')}

这个例子在 switch 语句中应用了字符串。第一个条件实际上应用的是表达式,求值为两个字符串 拼接后的后果。因为拼接后的后果等于 switch 的参数,所以 console.log 会输入 hello,xhs-rookies。可能在条件判断中应用表达式,就能够在判断中退出更多逻辑:

let xhsNumber = 25switch (true) {case xhsNumber < 0:    console.log('xhsNumber less than 0.')    break  case xhsNumber >= 0 && xhsNumber <= 10:    console.log('xhsNumber between 0 and 10.')    break  case xhsNumber > 10 && xhsNumber <= 20:    console.log('xhsNumber between 10 and 20.')    break  default:    console.log('xhsNumber more than 20.')}

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

try/catch 语句

try/catch 语句,作为在 JavaScript 中解决异样的一种形式,根本的语法如下所示:

try {// 可能出错的代码} catch (error) {// 出错时要做什么}

任何可能出错的代码都应该放到 try 块中,而处理错误的代码则放在 catch 块中,如下所示:

try {dosome...} catch (error) {console.log("An error happened!");}

如果 try 块中有代码产生谬误,代码会立刻退出执行,并跳到 catch 块中。catch 块此时接管到一个对象,该对象蕴含产生谬误的相干信息。

try/catch 语句中可选的 finally 子句始终运行。如果 try 块中的代码运行完,则接着执行 finally 块中的代码。如果出错并执行 catch 块中的代码,但 finally 块中的代码仍执行。trycatch 块无奈阻止 finally 块执行,包含 return 语句

try {return 2} catch (error) {return 1} finally {return 0}

在这个 try/catch 语句的各个局部都只放了一个 return 语句。看起来该函数应该返回 2,因为它在 try 块中,不会导致谬误。然而,finally 块的存在导致 try 块中的 return 语句被疏忽。因而,无论什么状况下调用该 try/catch 都会返回 0。如果去掉 finally 子句,该函数会返回 2。如果写出 finally 子句,catch 块就成了可选的。

自测题目

一、下列代码输入什么?

let xhsA = 1,  xhsB = 0while (xhsA <= 100) {xhsB = xhsB + xhsA  xhsA++}console.log(xhsB)let xhsC = 1,  xhsD = 0do {xhsD = xhsD + xhsC  xhsA++} while (xhsC <= 100)console.log(xhsD)let xhsE = 0for (let xhsF = 1; xhsF <= 100; xhsF++) {xhsE += xhsF}console.log(xhsE)

二、下列代码输入什么?

let xhsType = 'teacher'switch (xhsType) {case 'student':    console.log('我是 student!')    break  case 'teacher':    console.log('我是 teacher!')  case 'parent':    console.log('我是 parent!或者 我是 teacher')    break  default:    console.log('我是 person!')}

三、下列代码输入什么?

try {
  let xhsNumber1 = 10
  console.log(xhsNumber1)
} catch (error) {
  let xhsNumber2 = 10 / 2
  console.log(xhsNumber2)
} finally {
  let xhsNumber3 = 10 / 5
  console.log(xhsNumber3)
}

题目解析

一、

Answer:

Answer 5050 5050 5050

此题目考查的是 whiledo whilefor 循环语句,第一个 while 循环一开始定义 xhsA=1, 满足小于等于 100,所以循环执行 xshB = xhsB + xhsA;xhsA++; 直到 xshA 不满足小于等于 100,退出循环,此循环等价于 1+2+3+4+······+99+100=5050;第二个 do while 循环,和 while 循环过程一样,惟一区别是,do while 循环不论什么条件,先执行一遍块内代码,而后判断 xhsC 是否满足小于等于 100,最初输入后果 5050;for 循环一开始定义 xhsF=1, 满足小于等于 100,所以循环执行 xhsE+=xhsF; 直到 xhsF 不满足小于等于 100,退出循环,此循环也等价于 1+2+3+4+······+99+100=5050

二、

Answer:

Answer 我是 teacher! 我是 parent!或者 我是 teacher

此题目考查的是 switch 循环语句,一开始定义 xhsType = 'teacher'; 传入 switch 语句中,匹配到 case 'teacher': 执行前面的语句,输入“我是 teacher!”,因为前面没有 break; 语句跳出循环,所以继续执行前面的语句输入“我是 parent!或者 我是 teacher”,遇到 break; 跳出循环

三、

Answer 10 2

此题目考查的是 try/catch 语句,在 try 块中定义了 xhsNumber1 的值为 10,而后打印输出,这个过程并没有谬误抛出,所以 catch 块中代码不会被执行,然而 finally 中的代码,不论 try 块中有没有谬误抛出,都会执行,所以输入 xhsNumber3 的值 2

正文完
 0