9月阅读周·JavaScript权威指南:语句,跳转篇
背景
去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。
没有计划的阅读,收效甚微。
新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。
这个“玩法”虽然常见且板正,但是有效,已经坚持阅读七个月。
已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》。
当前阅读周书籍:《JavaScript权威指南》。
跳转
标签语句
语句是可以添加标签的,标签是由语句前的标识符和冒号组成:
identifer:statement
通过给语句定义标签,就可以在程序的任何地方通过标签名引用这条语句。也可以对多条语句定义标签,尽管只有在给语句块定义标签时它才更有用,比如循环和条件判断语句。通过给循环定义一个标签名,可以在循环体内部使用break和continue来退出循环或者直接跳转到下一个循环的开始。break和continue是JavaScript中唯一可以使用语句标签的语句。本章接下来会有讲述。这里有一个例子,其中while循环定义了一个标签,continue语句使用了这个标签:
mainloop:while(token!=null){//忽略这里的代码...
continue mainloop;//跳转到下一次循环
//忽略这里的代码...
}
这里用做标签的identifier必须是一个合法的JavaScript标识符,而不能是一个保留字。标签的命名空间和变量或函数的命名空间是不同的,因此可以使用同一个标识符作为语句标签和作为变量名或函数名。语句标签只有在它所起作用的语句(当然也可以在它的子句中)内是有定义的。一个语句标签不能和它内部的语句标签重名,但在两个代码段不相互嵌套的情况下是可以出现同名的语句标签的。带有标签的语句还可以带有标签,也就是说,任何语句可以有很多个标签。
break语句
单独使用break语句的作用是立即退出最内层的循环或switch语句。它的语法如下:
break;
由于它能够使循环和switch语句退出,因此这种形式的break只有出现在这类语句中才是合法的。
我们在switch语句的例子中已经见到过break语句。在循环中,不论出于什么原因,只要不想继续执行整个循环,就可以用break来提前退出。当循环终止条件非常复杂时,在函数体内使用break语句实现这些条件判断的做法要比直接在循环表达式中写出这个复杂终止条件的做法简单很多。下面的例子中的循环遍历整个数组元素来查找某个特定的值,当整个数组遍历完成后会正常退出循环,如果找到了需要查找的数组元素,则使用break语句退出循环:
for(var i=0;i<a.length;i++){
if(a[i]==target)break;
}
JavaScript中同样允许break关键字后面跟随一个语句标签(只有标识符,没有冒号):
break labelname;
当break和标签一块使用时,程序将跳转到这个标签所标识的语句块的结束,或者直接终止这个闭合语句块的执行。当没有任何闭合语句块指定了break所用的标签,这时会产生一个语法错误。当使用这种形式的break语句时,带标签的语句不应该是循环或者switch语句,因为break可以“跳出”任何闭合的语句块。这里的语句可以是由花括号括起来的一组语句,使用同一个标签来标识这一组语句。
在break关键字和labelname之间不能换行。因为JavaScript可以给语句自动补全省略掉的分号,如果break关键字和标签之间有换行,JavaScript解释器会认为你在使用break不带标签的最简形式,因此会在break后补充分号。
当你希望通过break来跳出非就近的循环体或者switch语句时,就会用到带标签的break语句。下面是示例代码:
var matrix=getData();//从某处得到一个二维数组
//将矩阵中所有元素进行求和
var sum=0,success=false;//从标签名开始,以便在报错时退出程序
compute_sum:if(matrix){
for(var x=0;x<matrix.length;x++){
var row=matrix[x];
if(!row)break compute_sum;
for(var y=0;y<row.length;y++){
var cell=row[y];
if(isNaN(cell))break compute_sum;
sum+=cell;
}
}
success=true;
}
//break语句跳转至此
//如果在success==false的条件下到达这里,说明我们给出的矩阵中有错误
//否则将矩阵中所有的元素进行求和
continue语句
continue语句和break语句非常类似,但它不是退出循环,而是转而执行下一次循环。continue语句的语法和break语句语法一样简单:
continue;
continue语句同样可以带有标签:
continue labelname;
不管continue语句带不带标签,它只能在循环体内使用。在其他地方使用将会报语法错误。
当执行到continue语句的时候,当前的循环逻辑就终止了,随即执行下一次循环,在不同类型的循环中,continue的行为也有所区别:
- 在while循环中,在循环开始处指定的expression会重复检测,如果检测结果为true,循环体会从头开始执行。
- 在do/while循环中,程序的执行直接跳到循环结尾处,这时会重新判断循环条件,之后才会继续下一次循环。
- 在for循环中,首先计算自增表达式,然后再次检测test表达式,用以判断是否执行循环体。
- 在for/in循环中,循环开始遍历下一个属性名,这个属性名赋给了指定的变量。
return语句
回想一下,函数调用是一种表达式,而所有表达式都有值。函数中的return语句既是指定函数调用后的返回值。这里是return语句的语法:
return expression;
return语句只能在函数体内出现,如果不是的话会报语法错误。当执行到return语句的时候,函数终止执行,并返回expression的值给调用程序。例如:
function square(x){return x*x;}//一个包含return语句的函数
square(2)//调用结果为4
如果没有return语句,则函数调用仅依次执行函数体内的每一条语句直到函数结束,最后返回调用程序。这种情况下,调用表达式的结果是undefined。return语句经常作为函数内的最后一条语句出现,但并不是说要一定放在函数最后,即使在执行return语句的时候还有很多后续代码没有执行到,这时函数也还会返回调用程序。
return语句可以单独使用而不必带有expression,这样的话函数也会向调用程序返回undefined。例如:
function display_object(o){//如果参数是null或者undefined则立即返回
if(!o)return;//其他的逻辑
}
总结
JavaScript中另一类语句是跳转语句(jump statement)。从名称就可以看出,它使得JavaScript的执行可以从一个位置跳转到另一个位置。break语句是跳转到循环或者其他语句的结束。continue语句是终止本次循环的执行并开始下一次循环的执行。JavaScript中的语句可以命名或带有标签,break和continue可以标识目标循环或者其他语句标签。
return语句让解释器跳出函数体的执行,并提供本次调用的返回值。throw语句触发或者“抛出”一个异常,它是与try/catch/finally语句一同使用的,这些语句指定了处理异常的代码逻辑。这是一种复杂的跳转语句,当抛出一个异常的时候,程序将跳转至最近的闭合异常处理程序,这个异常处理程序可以是在同一个函数中或者在更高层的调用栈中。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)