条件语句与循环语句

 默认情况下,javascript解释器依照语句的编写顺序依次执行。而javascript中的很多语句可以改变语句的默认执行顺序。本文介绍可以改变语句默认执行顺序的条件语句、循环语句。

 

条件语句

  脚本的威力体现在它们可以根据人们给出的各种条件做出决策,javascript使用条件语句来做判断

  条件语句(conditianal statement)通过判断表达式的值来决定执行还是跳过某些语句,包括if语句

【if语句】

  最常见的条件语句是if语句。if语句的条件必须放在if后面的圆括号内,条件的求值结果永远是一个布尔值,即只能是true或false。花括号中的语句,不管它们有多少条,只有在给定条件的求值结果是true的情况下才会执行

if(expression){
    statements;
}

  [注意]if语句中,括住expression的圆括号在语法上是必需的

  实际上,if语句中的花括号不是必不可少的。如果if语句中的花括号部分只包含一条语句,可以不使用花括号。但因为花括号可以提高脚本的可读性,所以在if语句中总是使用花括号是个好习惯

//可行,但不推荐
if(1>2)alert('1');

//推荐写法
if(1>2){
    alert('1');
}

 

  if语句根据表达式的值改变程序流程。当expression的值为true时执行跟在其后的代码块,当expression的值为false时,执行else的逻辑

if(expression)
    statement1
else
    statement2

  当在if/else语句中嵌套使用if语句时,必须注意确保else语句匹配正确的if语句

//错误暗示
if( i == j) if(j == k) console.log('i == k'); else console.log('i != j');

  javascript中的if/else匹配规则是:else总是和就近的if语句匹配

//实际解释
if( i == j){
    if(j == k)
        console.log('i == k');
    else
        console.log('i != j');//错误
}
//使用花括号
if(i == j){
    if(j == k){
        console.log('i == k');
    }
}else{
    console.log('i != j');
}

  当代码有多条分支时,需要使用else if语句。else if语句并不是真正的javascript语句,它是多条if/else语句连在一起时的一种惯用写法 

if(n == 1){
    //代码1
}else if(n == 2){
    //代码2
}else if(n == 3){
    //代码3
}else{
    //其他代码
}

  可以用if语句的嵌套形式来完成在语法上等价的代码,但没有else if语句清晰

if(n == 1){
    //代码1
}else{
    if(n == 2){
        //代码2
    }else{
        if(n == 3){
            //代码3
        }else{
           //其他代码
        }
    }
}

循环语句

  条件语句把javascript中的代码变成一条条的分支路径,而循环语句(looping statement)就是程序路径的一个回路,可以让一部分代码重复执行

  javascript有4种循环语句:while、do/while、for、for/in,它们的工作原理几乎一样:只要给定条件仍能得到满足,包含在循环语句里的代码就将重复地执行下去。一旦给定条件的求值结果不再是true,循环也就到此为止。其中最常用的循环就是对数组元素的遍历

【while语句】

  while语句属于前测试循环语句,也就是说,在循环体内的代码被执行之前,就会对出口条件求值

while(expression){
  statement
}

  当表达式expression是真值时则循环执行statement,直到expression的值为假值为止;如果是假值,那么程序将跳过循环

  [注意]使用while(true)会创建一个死循环

  大多数循环都会有一个像count这样的计数器变量。尽管循环计数器常用i、j、k这样的变量名,但如果想要让代码可读性更强,就应当使用更具语义的变量名

var count = 0;
while(count < 10){
    console.log(count);
    count++;
}

【do while语句】

  do while语句是后测试循环,即退出条件在执行循环内部的代码之后计算。这意味着在计算表达式之前,至少会执行循环主体一次

do{
    statement
}while(expression);

  do/while循环和普通的while循环有两点语法方面不同:

  【1】do/while循环要求必须使用关键字do来标识循环的开始,用while来标识循环的结尾并进入循环条件判断

  【2】do/while循环用分号结尾。如果while循环体使用花括号括起来,则while循环也不用使用分号做结尾

function printArray(a){
    var len = a.length,i=0;
    if(len == 0){
        console.log('empty');
    }else{
        do{
            console.log(a[i]);
        }while(++i<len);
    }
}

【for语句】

  for语句提供了一种比while语句更加方便的循环控制结构,用for循环来重复执行一些代码的好处是循环控制结构更加清晰

  大部分的循环都具有特定的计数器变量,计数器的三个关键操作是初始化、检测和更新。for语句将这三步明确声明为循环语法的一部分,各自使用一个表达式来表示

for(initialize;test;increment){
    statement;    
}
 
//等价于:
initialize;
while(test){
    statement
    increment;
}
 

  [注意]使用continue语句时,while循环和for循环并不等价

  initialize、test和increment三个表达式之间用分号分隔,它们分别负责初始化操作、循环条件判断和计数器变量的更新。将它们放在循环的第一行会更容易理解for循环正在做什么,而且也可以防止忘记初始化或者递增计数器变量

  initialize表达式只在循环开始之前执行一次;每次循环执行之前会执行test表达式,并判断表达式的结果来决定是否执行循环体,如果test计算结果为真值,则执行循环体中的statement,最后,执行increment表达式

  在for循环的变量初始化表达式中,也可以不使用var关键字,该变量的初始化可以在外部执行

var count = 10;
var i;
for(i = 0; i < count; i++){
    console.log(i);
}

  由于ECMAScript中不存在块级作用域,因此在循环内部定义的变量也可以在外部访问到

var count = 10;
for(var i = 0; i < count; i++){
    console.log(i);
}
console.log(i);//10

  for循环常见用途是对某个数组里的全体元素进行遍历处理

var beatles = Array('John','Paul','George','Ringo');
for(var count = 0; count < beatles.length; count++){
    alert(beatles[count]);
}

  如果循环中的一次迭代会改变多个变量,则需要用到逗号运算符,它将初始化表达式和自增表达式合并入一个表达式中以用于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*/;
    return o;
}

  for循环中的initialize、test和increment这三个表达式中的任何一个都可以忽略,但是两个分号必不可少。如果省略test表达式,那么这将是一个死循环。同样,和while(true)类似,死循环的另外一种写法是

for(;;)

【for in语句】

  for/in语句也使用for关键字,但它和常规的for循环是完全不同的一类循环

for(variable in object){
    statement
}

  variable通常是一个变量名,也可以是一个可以产生左值的表达式或一个通过var语句声明的变量,总之必须是一个适用于赋值表达式左侧的值。object是一个表达式,这个表达式的计算结果是一个对象。同样,statement是一个语句或语句块,它构成了循环的主体

  for/in循环可以用来更方便地遍历对象属性成员

for(var p in o){
    console.log(o[p]);
}

  在执行for/in语句的过程中,javascript解释器首先计算object表达式。如果表达式为null或undefined。javascript解释器将会跳过循环并执行后续的代码。如果表达式等于一个原始值,这个原始值将会转换为与之对应的包装对象(wrapper object)。否则,expression本身已经是对象了。javascript会依次枚举对象的属性来执行循环。然而,在每次循环前,javascript都会先计算variable表达式的值,并将属性名(一个字符串)赋值给它

  [注意]只要for/in循环中variable的值可以当做赋值表达式的左值,它可以是任意表达式,每次循环都会计算这个表达式,也就是说每次循环它计算的值有可能不同

var obj = {
  x: 1,
  y: 2
};
var props = [];
var i = 0;
for (props[i++] in obj);
props // ['x', 'y']

 

  javascript数组不过是一种特殊的对象,因此,for/in循环可以像枚举对象属性一样枚举数组索引

var o = {a: 1, b: 2, c: 3};
for (var i in o) {
  console.log(o[i]);
}
// 1
// 2
// 3

  [注意]for/in循环并不会遍历对象的所有属性,只有可枚举(enumerable)的属性才会遍历到

  ECMAScript规范并没有指定for/in循环按照何种顺序来枚举对象属性。但实际上,主流浏览器厂商的javascript实现是按照属性定义的先后顺序来枚举简单对象的属性,先定义的属性先枚举。如果使用对象直接量的形式创建对象,则将按照直接量中属性的出现顺序枚举。有一些网站和javascript库是依赖于这种枚举顺序的,浏览器厂商不大可能会修改这个顺序

 

 

 

 

posted @ 2021-12-14 09:16  赴人间惊鸿艳  阅读(387)  评论(0)    收藏  举报