标签:
为了理解“循环”,可以将在javascript中的代码想象成一条条的分支路径。循环语句就是程序路径的一个回路,可以让一部分代码重复执行。
常见的循环语句有:while、do/while、for和for/in。
(1)while
if语句是一种基本的控制语句,用来选择执行程序的分支语句。和if一样,while语句也是一个基本循环语句,它的语法如下:
while (expression){ statement; }
在执行while语句之前,Javascript解释器首先计算expression的值,如果它的值是假值,那么程序将跳过循环体中的逻辑statement转而执行程序中的下一条语句。反之,如果表达式expression是真值,Javascript解释器将执行循环体内的逻辑,然后再次计算表达式expression的值,这种循环会一直继续下去,直到expression的值为假值为止。
可以简单的理解为:当表达式expression是真值的时候,则循环执行statement,直到expression为假。
注意:使用while(true)则会创建一个死循环。
通常来说,使用时我们并不想让Javascript反复执行同一个操作。在几乎每一次循环中,都会有一个或多个变量随着循环的迭代而改变。正是由于改变了这些变量,因此每次循环执行的statement的操作也不尽相同。而且,如果改变的变量在expression中用到,那么每次循环表达式的值也不同。这一点非常重要,否则一个初始值为真值的表达式,它的值永远都真值,循环也不会结束。
var count = 0; while(count < 10) { console.log(count); count++; }
通过上述例子,可以看出变量count的初始值是0,在循环执行过程中,它的值每次都递增1。当循环执行了10次,表达式的值就变成了false(即,变量count的值不再小于10),这时while就会结束,Javascript解释器将执行程序中的下一条语句。大多数循环都会有一个像count这样的计数器便量,尽管循环计数器常用i、j、k这样的变量名,但如果想要让代码可读性更强,就应当使用更具语义的变量名。
(2)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循环的结尾也不会用到分号。
(3)for
for语句提供了一种比while语句更加方便的循环控制结构。for语句对常用的循环模式做了一些简化。大部分的循环都具有特定的计数器变量。在循环开始之前要初始化这个变量,然后在每次循环执行之前都检测一下它的值。最后,计数器变量做自增操作,否则就在循环结束后、下一次判断循环条件前做修改。在这一类循环中,计数器的三个关键操作是初始化、检测和更新。for语句就将这三步操作明确声明为循环语法的一部分,各自使用一个表达式来表示。for语句的语法如下:
for(initialize;test;increment){ statement }
initialize、test、increment三个表达式之间用分号隔开,它们分别负责初始化操作、循环条件判断和计数器变量的更新。将它们放在循环的第一行会更容易理解for循环正在做什么,而且也可以防止忘记初始化或者递增计数器变量。
要理解for循环是如何运作的,最简单的方法就是列出一个与之等价的while循环。(此时只是举例,while和for并不是等价的,比如在使用continue语句时)
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); }
当然,实际运用当中,可能会有一些循环比例子更加复杂,如果一次迭代需要改变多个变量,可以用逗号隔开,语法如下:
for (var count = 0; cont < 10; i++,j--,k++ ){ sum + = i * j - k; }
(4) 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,Javascript解释器将会跳过循环并执行后续的代码。如果表达式等于一个原始值,这个原始值将会转换为与之对应的包装对象。否则,expression本身已经是对象了。Javascript会依次枚举对象的属性来执行循环。然而在每次循环之前,Javascript都会先计算variable表达式的值,并将属性名(一个字符串)赋值给它。
需要注意一点,只要for/in循环中variable的值可以当做赋值表达式的左值,它它可以是任意表达式。每次循环都会计算这个表达式,也就是说每次循环,它计算的值都有可能是不同的,例如,可以使用下面代码将所所有对象属性赋值到一个数组当中:
var o = {x:1, y:2, z:3}; var a = [], i = o ; for(a[i++] in o) /* empty */;
Javascript数组不过是一种特殊的对象,因此for/in循环可以像枚举对象属性一样枚举数组索引。例如,在上面的代码之后加上这段代码就可以枚举数组的索引0、1、2:
for(i in a){ console.log(i); }
其实,for/in循环并不会遍历对象的所有属性,只有"可枚举"的属性才会被遍历到。
标签:
原文地址:http://my.oschina.net/u/2352178/blog/475795