9月阅读周·JavaScript权威指南:语句,循环篇
背景
去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。
没有计划的阅读,收效甚微。
新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。
这个“玩法”虽然常见且板正,但是有效,已经坚持阅读七个月。
已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》。
当前阅读周书籍:《JavaScript权威指南》。
循环
while
if语句是一种基本的控制语句,用来选择执行程序的分支语句。和if一样,while语句也是一个基本循环语句,它的语法如下:
while(expression)
statement
在执行while语句之前,JavaScript解释器首先计算expression的值,如果它的值是假值,那么程序将跳过循环体中的逻辑statement转而执行程序中的下一条语句。反之,如果表达式expression是真值,JavaScript解释器将执行循环体内的逻辑,然后再次计算表达式expression的值,这种循环会一直继续下去,直到expression的值为假值为止。换一种说法就是当表达式expression是真值时则循环执行statement,注意,使用while(true)则会创建一个死循环。
通常来说,我们并不想让JavaScript反复执行同一操作。在几乎每一次循环中,都会有一个或多个变量随着循环的迭代而改变。正是由于改变了这些变量,因此每次循环执行的statement的操作也不尽相同。而且,如果改变的变量在expression中用到,那么每次循环表达式的值也不同。这一点非常重要,否则一个初始值为真值的表达式的值永远都是真值,循环也不会结束,下面这个示例所示的while循环输出0~9之间的值:
var count=0;
while(count<10){
console.log(count);
count++;
}
可以发现,在这个例子中,变量count的初始值是0,在循环执行过程中,它的值每次都递增1。当循环执行了10次,表达式的值就变成了false(即,变量count的值不再小于10),这时while就会结束,JavaScript解释器将执行程序中的下一条语句。大多数循环都会有一个像count这样的计数器变量。尽管循环计数器常用i、j、k这样的变量名,但如果想要让代码可读性更强,就应当使用更具语义的变量名。
do/while
do/while循环和while循环非常相似,只不过它是在循环的尾部而不是顶部检测循环表达式,这就意味着循环体至少会执行一次。do/while循环的语法如下:
do
statement
while(expression);
do/while循环并不像while循环那么常用。这是因为在实践中那种想要循环至少一次的情况并不常见,下面是一个do/while循环的例子:
function printArray(a){
var len=a.length,i=0;
if(len==0)
console.log("Empty Array");
else{
do{
console.log(a[i]);
}while(++i<len);
}
}
在do/while循环和普通的while循环之间有两点语法方面的不同之处。首先,do循环要求必须使用关键字do来标识循环的开始,用while来标识循环的结尾并进入循环条件判断;其次,和while循环不同,do循环是用分号结尾的。如果while的循环体使用花括号括起来的话,则while循环也不用使用分号做结尾。
for
for语句提供了一种比while语句更加方便的循环控制结构。for语句对常用的循环模式做了一些简化。大部分的循环都具有特定的计数器变量。在循环开始之前要初始化这个变量,然后在每次循环执行之前都检测一下它的值。最后,计数器变量做自增操作,否则就在循环结束后、下一次判断循环条件前做修改。在这一类循环中,计数器的三个关键操作是初始化、检测和更新。for语句就将这三步操作明确声明为循环语法的一部分,各自使用一个表达式来表示。for语句的语法如下:
for(initialize;test;increment)
statement
initialize、test和increment三个表达式之间用分号分隔,它们分别负责初始化操作、循环条件判断和计数器变量的更新。将它们放在循环的第一行会更容易理解for循环正在做什么,而且也可以防止忘记初始化或者递增计数器变量。
要解释for循环是如何工作的,最简单的方法莫过于列出一个与之等价的while循环。
initialize;
while(test){
statement
increment;
}
换句话说,initialize表达式只在循环开始之前执行一次。初始化表达式应当具有副作用(通常是一条赋值语句)。JavaScript同样允许初始化表达式中带有var变量声明语句,这样的话就可以同时声明并初始化一个计数变量。每次循环执行之前会执行test表达式,并判断表达式的结果来决定是否执行循环体,如果test计算结果为真值,则执行循环体中的statement。最后,执行increment表达式。同样,为了有用起见,这里的increment表达式也必须具有副作用。通常来讲,它不是一个赋值表达式就是一个由“++”或“--”运算符构成的表达式。
在上文中的while循环的例子可以使用for循环来重写,这个循环同样输出数字0~9:
for(var count=0;count<10;count++)
console.log(count);
当然,有些循环会比这些例子更加复杂,而且循环中的一次迭代会改变多个变量。在JavaScript中,这种情况则必须用到逗号运算符,它将初始化表达式和自增表达式合并入一个表达式中以用于for循环:
var i,j;
for(i=0,j=10;i<10;i++,j--)
sum+=i*j;
到目前为止,在示例代码中的循环变量都是数字。当然数字是最常用的,但不是必需的。下面这段代码就使用for循环来遍历链表数据结构,并返回链表中的最后一个对象(也就是第一个不包含next属性的对象):
function tail(o){//返回链表的最后一个节点对象
for(;o.next;o=o.next)/*empty*/;//根据判断o.next是不是真值来执行遍历
return o;
}
需要注意的是,这段代码不包含initialize表达式,for循环中那三个表达式中的任何一个都可以忽略,但是两个分号必不可少。如果省略test表达式,那么这将是一个死循环,同样,和while(true)类似,死循环的另外一种写法是for(;;)。
for/in
for/in语句也使用for关键字,但它是和常规的for循环完全不同的一类循环。for/in循环语句的语法如下:
for(variable in object)
statement
variable通常是一个变量名,也可以是一个可以产生左值的表达式或者一个通过var语句声明的变量,总之必须是一个适用于赋值表达式左侧的值。object是一个表达式,这个表达式的计算结果是一个对象。同样,statement是一个语句或语句块,它构成了循环的主体。
使用for循环来遍历数组元素是非常简单的:
for(var i=0;i<a.length;i++)//i代表了数组元素的索引
console.log(a[i]);//输出数组中的每个元素
而for/in循环则是用来更方便地遍历对象属性成员:
for(var p in o)//将属性名字赋值给变量p
console.log(o[p]);//输出每一个属性的值
在执行for/in语句的过程中,JavaScript解释器首先计算object表达式。如果表达式为null或者undefined,JavaScirpt解释器将会跳过循环并执行后续的代码。如果表达式等于一个原始值,这个原始值将会转换为与之对应的包装对象(wrapper object)(见3.6节)。否则,expression本身已经是对象了。JavaScript会依次枚举对象的属性来执行循环。然而在每次循环之前,JavaScript都会先计算variable表达式的值,并将属性名(一个字符串)赋值给它。
总结
为了理解条件语句,可以将在JavaScript中的代码想象成一条条的分支路径。循环语句(looping statement)就是程序路径的一个回路,可以让一部分代码重复执行。JavaScript中有4种循环语句:while、do/while、for和for/in。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)