9月阅读周·JavaScript权威指南:语句,条件语句篇
背景
去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。
没有计划的阅读,收效甚微。
新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。
这个“玩法”虽然常见且板正,但是有效,已经坚持阅读七个月。
已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》。
当前阅读周书籍:《JavaScript权威指南》。
条件语句
if
if语句是一种基本的控制语句,它让JavaScript程序可以选择执行路径,更准确地说,就是有条件地执行语句,这种语句有两种形式,第一种是:
if(expression)
statement
在这种形式中,需要计算expression的值,如果计算结果是真值,那么就执行statement。如果expression的值是假值,那么就不执行statement。例如:
if(username==null)//如果username是null或者undefined
username="John Doe";//对其进行定义
同样地:
//如果username是null、undefined、false、0、""或者NaN,那么给它赋一个新值
if(!username)username="John Doe";
需要注意的是,if语句中括住expression的圆括号在语法上是必需的。
JavaScript语法规定,if关键字和带圆括号的表达式之后必须跟随一条语句,但可以使用语句块将多条语句合并成一条。因此,if语句的形式如下所示:
if(!address){
address="";
message="Please specify a mailing address.";
}
if语句的第二种形式引入了else从句,当expression的值是false的时候执行else中的逻辑。其语法如下:
if(expression)
statement1
else
statement2
在这段代码中,当expression为真值时执行statement1,当expression为假值时执行statement2,例如:
if(n==1)
console.log("You have 1 new message.");
else
console.log("You have"+n+"new messages.");
当在if/else语句中嵌套使用if语句时,必须注意确保else语句匹配正确的if语句。考虑如下代码:
i=j=1;
k=2;
if(i==j)
if(j==k)
console.log("i equals k");
else
console.log("i doesn't equal j");//错误!!
在这个示例中,内层if语句构成了外层if语句所需要的子句。但是,if和else的匹配关系并不清晰(只有缩进给出了一些暗示),而且在这个例子中,缩进给出的暗示是错误的,因为JavaScript解释器将上述代码实际解释为:
if(i==j){
if(j==k)
console.log("i equals k");
else
console.log("i doesn't equal j");//错误!
}
和大多数编程语言一样,JavaScript中的if、else匹配规则是,else总是和就近的if语句匹配。为了让这个例子可读性更强、更易理解、更方便维护和调试,应当适当地使用花括号:
if(i==j){
if(j==k){
console.log("i equals k");
}
}
else{//花括号让代码结构更加清晰
console.log("i doesn't equal j");
}
虽然这并不是本书中所使用的编码风格,但许多程序员都有将if和else语句主体用花括号括起来的习惯(就像在类似while循环这样的复合语句中一样),即便每条分支只有一条语句,但坚持这样做可以避免刚才这种程序歧义的问题。
else if
if/else语句通过判断一个表达式的计算结果来选择执行两条分支中的一条。但当代码中有多条分支的时候该怎么办呢?一种解决办法是使用else if语句。else if语句并不是真正的JavaScript语句,它只不过是多条if/else语句连在一起时的一种惯用写法。
if(n==1){//执行代码块1
}
else if(n==2){//执行代码块2
}
else if(n==3){//执行代码块3
}
else{//之前的条件都为false,则执行这里的代码块4
}
这种代码并没有什么特别之处,它由多条if语句组成,每条if语句的else从句又包含另外一条i f语句。可以用i f语句的嵌套形式来完成在语法上等价的代码,但与之相比,显然使用else if写法更清晰也更可取:
if(n==1){//执行代码块1
}
else{
if(n==2){//执行代码块2
}
else{
if(n==3){//执行代码块3
}
else{//如果所有的判断都是false,执行代码块4
}
}
}
switch
if语句在程序执行过程中创建一条分支,并且可以使用else if来处理多条分支。然而,当所有的分支都依赖于同一个表达式的值时,else if并不是最佳解决方案。在这种情况下,重复计算多条if语句中的条件表达式是非常浪费的做法。
switch语句正适合处理这种情况。关键字switch之后紧跟着圆括号括起来的一个表达式,随后是一对花括号括起来的代码块:
switch(expression){
statements
}
然而,switch语句的完整语法要比这复杂一些。代码块中可以使用多个由case关键字标识的代码片段,case之后是一个表达式和一个冒号,case和标记语句很类似,只是这个标记语句并没有名字,它只和它后面的表达式关联在一起。当执行这条switch语句的时候,它首先计算expression的值,然后查找case子句中的表达式是否和expression的值相同(这里的“相同”是按照“===”运算符进行比较的)。如果找到匹配的case,那么将会执行这个case对应的代码块。如果找不到匹配的case,那么将会执行"default:"标签中的代码块。如果没有"default:"标签,switch语句将跳过它的所有代码块。
switch语句是非常容易引起混淆的。用例子来解释会比较清晰一些,下面的switch语句和方才展示的if/else语句是等价的:
switch(n){
case 1://如果n===1,从这里开始执行
//执行代码块1
break;//停止执行switch语句
case 2://如果n===2,从这里执行
//执行代码块2
break;//在这里停止执行switch语句
case 3://如果n===3,从这里执行
//执行代码块3
break;//在这里停止执行switch语句
default://如果所有的条件都不匹配
//执行代码块4
break;//在这里停止执行switch语句
}
下面的switch语句的例子更加贴近实战,它根据值的类型将该值转换为字符串:
function convert(x){
switch(typeof x){
case'number'://将数字转换为十六进制数
return x.toString(16);
case'string'://返回两端带双引号的字符串
return'"'+x+'"';
default://使用普通的方法转换其他类型
return String(x);
}
}
注意,在上面两个例子中,case关键字后跟随的是数字和字符串直接量,在实际中这是switch语句最常见的用法,但是ECMAScript标准允许每个case关键字跟随任意的表达式。
switch语句首先计算switch关键字后的表达式,然后按照从上到下的顺序计算每个case后的表达式,直到执行到case的表达式的值与switch的表达式的值相等时为止。由于对每个case的匹配操作实际上是“===”恒等运算符比较,而不是“==”相等运算符比较,因此,表达式和case的匹配并不会做任何类型转换。
由于每次执行switch语句的时候,并不是所有的case表达式都能执行到,因此,应当避免使用带有副作用的case表达式,比如函数调用表达式和赋值表达式。最安全的做法就是在case表达式中使用常量表达式。
总结
条件语句是通过判断指定表达式的值来决定执行还是跳过某些语句。这些语句是代码的“决策点”,有时称为“分支”。如果说JavaScript解释器是按照代码的“路径”执行的,条件语句就是这条路径上的分叉点,程序执行到这里时必须选择其中一条路径继续执行。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)