《JavaScript高级程序设计》第三版 笔记
3.6 语句
ECMAScript-262 规定了一组语句(也称为流控制语句)。
从本质上看,语句定义了 ECMAScript 中的主要语法,语句通常使用一或多个关键字来完成给定任务。
语句可以很简单,例如通知函数退出;也可以比较复杂,例如指定重复执行某个命令的次数。
3.6.1 if语句
if (condition) {
statement1;
} else {
statement2;
}
condition(条件)可以是任意表达式。
如果这个表达式的结果不是布尔值,就会自动调用 Boolean() 转换函数将这个表达式的结果转换为一个布尔值。
如果对 condition 求值结果为 true ,则执行 statement1 ,为 false 则执行 statement2 。
3.6.2 do-while 语句
do-while 语句是一种后测试循环语句,即只有在循环体中的代码执行之后,才会测试出口条件。
在对条件表达式求值之前,循环体中的代码至少会被执行一次。
do {
statement;
} while (expression);
example:
var i = 0;
do {
i += 2;
} while (i<10);
alert(i);
3.6.3 while 语句
while 语句属于前测试循环语句,即在循环体内的代码被执行之前,就会对出口条件求值。
因此,循环体内的代码有可能永远不会被执行。
while(expression) {
statement;
}
example:
var i = 0;
while (i < 10) {
i += 2;
}
3.6.4 for语句
for 语句也是一种前测试循环语句,但它具有在执行循环之前初始化变量和定义循环后要执行的代码的能力。
for (initialization; expression; post-loop-expression){
statement;
}
只有当条件表达式返回 true 的情况下才会进入 for 循环,因此也有可能不会执行循环体中的代码。
如果执行了循环体中的代码,则一定会对循环后的表达式求值。
使用 while 循环做不到的,使用 for 循环也同样做不到。即 for 循环只是把与循环有关的代码集中在了一个位置。
下列 for 循环语句与 while 语句功能相同:
var count = 10;
for (var i=0; i<count; i++){
alert(i);
}
var count = 10;
var i = 0;
while (i<count){
alert(i);
i++;
}
在 for 循环的变量初始化表达式中,也可以不使用 var 关键字。该变量的初始化可以在外部执行。
example:
var count = 10;
var i;
for (i=0; i<count; i++){
alert(i);
}
由于 ECMAScript 中不存在块级作用域,因此在循环内部定义的变量也可以在外部访问到。
example:
for(var i=0,count=10; i<count; i++){
console.log(i); //0,1,2,3,4,5,6,7,8,9
}
console.log("------");
console.log(i); //10
console.log("------");
for(var i=0,count=10; i<count; ++i){
console.log(i); //0,1,2,3,4,5,6,7,8,9
}
for 语句中的初始化表达式、控制表达式和循环后表达式都是可选的。
将这两个表达式全部省略,就会创建一个无限循环。
example:
for (;;){ //无限循环
doSomething();
}
只给出控制表达式实际就把 for 循环转换成了 while 循环。
example:
var count = 10;
var i = 0;
for (; i<count;){
alert(i);
i++;
}
3.6.5 for-in 语句
for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。
for (property in expression){
statement;
}
使用 for-in 循环来显示 BOM 中 window 对象的所有属性;
每次执行循环时,都会将 window 对象中存在的一个属性名赋值给变量 propName ;
这个过程一直持续到对象中的所有属性都被枚举一遍为止。
属性没有顺序, for-in 循环输出的属性名顺序是不可预测的。
与 for 语句类似,这里控制语句中的 var 操作符也不是必需的。但是为了保证使用局部变量,还是推荐下面例子的做法。
example:
for (var propName in window){
document.write(propName + "\t");
}
如果表示要迭代的对象的变量值为 null 或 undefined , for-in 语句将不执行循环体(ECMAScript 5 之前会抛出错误)。
使用 for-in 循环之前,先检测确认该对象的值不是 null 或 undefined 。
(safari 3 以前的版本有个bug会导致某些属性被返回两次。)
3.6.6 label 语句
使用 label 语句可以在代码中添加标签,以便将来使用。
label:statement
example:
start: for (var i=0;i<count;i++){
alert(i);
}
这个例子中定义的 start 标签可以在将来由 break 或 continue 语句引用。
加标签的语句一般都要与 for 语句等循环语句配合使用。
3.6.7 break 和 continue 语句
break 和 continue 语句用于在循环中精确地控制代码的执行。
break 语句会立即退出循环,强制继续执行循环后面的语句。
continue 语句也会立即退出循环,但退出循环后会从循环的顶部继续执行。
example:
var num = 0;
for (var i=1; i<10; i++){
if (i % 5 == 0){
break;
}
console.log(i); //1,2,3,4
num++;
}
console.log(num); //4
var num = 0;
for (var i=1; i<10; i++){
if(i % 5 == 0){
continue;
}
console.log(i); //1,2,3,4, 6,7,8,9
num++;
}
console.log(num); //8
break 和 continue 语句都可以与 label 语句联合使用,从而返回代码中特定的位置;
这种情况多发生在循环嵌套的情况下。
联用 break 、continue 和 label 语句能够执行复杂的操作,但如果使用过度,不利于调试。因此 label 语句一定要使用描述性标签,同时不要嵌套过多的循环。
example:
var num3 = 0;
outermost:
for (var i=1; i<4; i++){
for (var j=1; j<4; j++){
if (i % 2 ==0 && j % 2 ==0){
break outermost;
}
console.log("j" + j);
}
console.log("i" + i);
num3++;
}
console.log("num3" + "\t" + num3);
var num4 = 0;
outermost:
for (var i=1; i<4; i++){
for (var j=1; j<4; j++){
if (i % 2 ==0 && j % 2 ==0){
continue outermost;
}
console.log("j" + j);
}
console.log("i" + i);
num4++;
}
console.log("num4" +"\t" + num4);
3.6.8 with 语句
with 语句的作用是将代码的作用域设置到一个特定的对象中。
with (expression){
statement;
}
定义 with 语句的目的主要是为了简化多次编写同一个对象的工作。
example:
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
上面几行代码都包含 location 对象。如果使用 with 语句,可以改写成:
with (location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
在这个重写的例子中,使用 with 语句关联了 location 对象;
在 with 语句代码块内部,每个变量首先被认为是一个局部变量;
如果在局部变量中找不到该变量的定义,就会查询 location 对象中是否有同名的属性;
如果发现了同名属性,则以 location 对象属性的值作为变量的值。
*严格模式下不允许使用 with 语句,否则将视为语法错误。
*大量使用 with 语句会导致性能下降,同时也会给调试代码造成困难,因此在开发大型应用程序时,不建议使用 with 语句。
3.6.9 switch 语句
switch 语句与 if 语句的关系最为密切,而且也是在其他语言中普遍使用的一种流控制语句。
switch (expression){
case value:
statement;
break;
case value:
statement;
break;
case value:
statement;
break;
case value:
statement;
break;
default: statement;
}
每一种 case (情形)的含义是:如果表达式等于这个值(value),则执行后面的语句(statement);
break 语句会导致代码执行流跳出 switch 语句;
如果省略 break 关键字,就会导致执行完当前的 case 后,继续执行下一个 case(通过为每个 case 后面都添加一个 break 语句,可以避免同时执行多个 case 代码的情况);
default 关键字用于在表达式不匹配前面任何一种情形的时候,执行机动代码(因此也相当于一个 else 语句)。
优点:
避免多重 else if 语句。
example:
if (i == 25){
alert("25");
}else if (i == 35){
alert("35");
}else if (i == 45){
alert("45");
}else {
alert("other");
}
与此等价的 switch 语句:
switch (i){
case 25:
alert("25");
break;
case 35:
alert("35");
break;
case 45:
alert("45");
break;
default:
alert("other");
}
几种情形混合:
需要混合几种情形,最好在代码中添加注释,说明是有意省略 break 关键字。
example:
switch (i){
case 25:
/*合并两种情形*/
case 35:
alert("25 or 35");
break;
case 45:
alert("45");
break;
default:
alert("other");
}
可以使用任何数据类型
在 switch 语句中使用字符串、对象都没问题;
每个 case 的值不一定是常量,可以是变量,甚至是表达式。
switch 语句在比较值时使用的是 全等操作符 ,因此不会发生类型转换(例如 “10”不等于10。) 。
example:
switch ("hello world"){
case "hello" + "world":
alert("Greeting was found.");
break;
case "goodbye":
alert("Closing was found.");
break;
default:
alert("Unexpected message was found.");
}
var num = 25;
switch (true){
case num < 0:
alert("Less than 0.");
break;
case num >= 0 && num <= 10:
alert("Between 0 and 10.")
break;
case num >10 && num <= 20:
alert("Between 10 and 20.");
break;
default:
alert("More than 20.");
}