在 JavaScript 标准中,把语句分成了两种:声明和语句;不过,他们的区分逻辑需要整理一下。
- 普通语句
- 语句块
- 空语句
- 表达式语句
- if 语句
- switch 语句
- 循环语句
- for 循环
- for in 循环
- for of 循环
- for await of 循环
- while 循环
- do while 循环
- return 语句
- break 语句
- continue 语句
- with 语句
- throw 语句
- try 语句
- debugger 语句
- 声明型语句
- var 语句
- let 语句
- const 语句
- class 语句
- 函数声明
- 普通函数声明
- async 函数声明
- generator 函数声明
- async generator 函数声明
根据上面的分类,对这些语句进行学习。
语句块
简单的理解,语句块就是一对大括号,如下:
1 | { |
语句块的意义和好处在于,让我们可以把多行语句视为同一行语句,这样,if、for 等语句定义起来更为简单;不过,语句块也会产生作用域,如下:
1 | { |
这里的 let 声明仅仅对语句块的作用域生效,于是在语句块外部试图访问语句块内部的变量就会报错。
空语句
空语句就是一个独立的分号,如下:
1 | ; |
空语句的存在是从语言设计完备性的角度考虑,允许插入多个分号而不抛出错误。
if 语句
if 语句是平时编码过程中很熟悉的条件判断语句,在满足条件时执行它里面对应的代码,它还可以有不同的分支结构,在满足不同条件时分别执行对应的条件块。
switch 语句
switch 语句和 if … else … 的功能类似,都是用不同的分支条件来只执行对应的分支结构,但是需要注意的是在各个分支结构中有 break 和没有 break 的情况。
循环语句(while、do…while)
while 和 do…while 也是经常使用的一类循环处理语句,那么他们两者到底有什么区别?
区别其实很简单,在 do…while 中循环体至少执行一次,而 while 有可能不会执行。
普通 for 循环
for 循环在冒泡排序算法中经常使用,那么它的使用也不多做介绍,看几个普通实例:
1 | for (i = 0; i < 100; i++) { |
for in 循环
for in 循环枚举对象的所有属性,这里可以体现对象的 enumerable 特征,如下:
1 | let obj = {a: 1, b: 2}; |
for of 循环
for of 循环也是一个经常使用的语法,它可以用于数组,例如:
1 | for(let item of [1,2,3,4]) { |
这里打印出了数组的所有数据,实际上它背后的原理是 iterator 机制。可以给任何一个对象添加 iterator,使它可以用于 for of 语句。
return、break、continue
return 语句用于函数中,它终止函数的执行并且指定函数的返回值;
break 语句用于跳出循环或者 switch 语句;
continue 语句用于结束本次循环开始下一次循环;
break 和 continue 这两个语句都属于控制语句,用法也比较相似,唯一的不同就是他们控制的循环在处理时跳出的结果不一样。
with 语句
with 语句是一个历史写法,它可以把对象的属性在它内部的作用域变成变量,如下:
1 | let obj = {a: 1, b: 2}; |
这个语句现在不推荐使用,因为它在处理数据时会改变数据定义时的环境,行为不一,不太好控制。
try 语句和 throw 语句
try 语句和 throw 语句用于异常处理,它们配合使用,在处理异常情况下非常有用。
debugger 语句
debugger 语句通知调试器在此处断点,方便调试,而在调试器不挂载的情况下,它没有任何作用。
var、let、const
var 语句是古老的 JavaScript 语句声明变量的方法;
let、const 是 ES6 中新的变量声明方法,它们特性非常相似,在处理声明变量的过程中和 var 的区别是对作用域的影响范围不一样。
class 声明
目前,class 声明只能写在构造函数中,它展示了构造函数、getter 和 setter 等方法的处理。
函数声明 function
在前面学习了函数声明对全局作用域的影响,这里再学一下函数声明的几种类型:
1 | function foo() {} |
最后,这里对语句部分进行了整体的构思学习,从分成普通语句和声明语句的角度进行了处理,利于记忆。