首页 > 代码库 > JavaScript基本概念(二)

JavaScript基本概念(二)

加性操作符

加法和减法这两个加性操作符应该说是编程语言中最简单的算术操作符了。但是在 ECMAScript 中,这两个操作符却都有一系列的特殊行为。与乘性操作符类似,加性操作符也会在后台转换不同的数据类型。然而,对于加性操作符而言,相应的转换规则还稍微有点复杂。

加法

加法操作符(+)的用法如下所示:

var result = 1 + 2;

如果两个操作符都是数值,执行常规的加法计算,然后根据下列规则返回结果:

  • 如果有一个操作数是 NaN ,则结果是 NaN ;
  • 如果是 Infinity 加 Infinity ,则结果是 Infinity ;
  • 如果是 -Infinity 加 -Infinity ,则结果是 -Infinity ;
  • 如果是 Infinity 加 -Infinity ,则结果是 NaN ;
  • 如果是+0 加+0,则结果是0;
  • 如果是-0 加-0,则结果是0;
  • 如果是+0 加-0,则结果是0。

不过,如果有一个操作数是字符串,那么就要应用如下规则:

  • 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;
  • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来。

即一个操作数是字符串,另外一个是数值或布尔值,则调用String()类型转换方法取得相应的字符串值,然后再应用前面关于字符串的规则。对于 undefined 和 null ,也是一样的,通过String()类型转换方法后取得”undefined” 和 “null” 。如果另一个是对象,那么就调用valueOf()方法获取到操作值,如果没有valueOf()方法就调用该对象的toString()方法获取操作值应用上述规则。

只要两个操作数,其中任意一个都不是字符串,那么都会通过Number()类型转换函数尝试把两个操作数转换为数值,然后再做加法运算。

    var temp1=true;
    var temp2=false;
    alert(temp2+temp1); // 1
    var o={
        valueOf:function(){
            var tempx=true;
            return tempx;
        },
        toString:function(){
            return 123;
        }
    };
    var temp1=132;
    alert(temp1+o); // 133
var result2 = 5 + "5"; // 一个数值和一个字符串相加
alert(result2); // "55"

减法

减法操作符(-)是另一个极为常用的操作符,其用法如下所示:

var result = 2 - 1;

与加法操作符类似,ECMAScript 中的减法操作符在处理各种数据类型转换时,同样需要遵循一些特殊规则,如下所示:

  • 如果两个操作符都是数值,则执行常规的算术减法操作并返回结果;
  • 如果有一个操作数是 NaN ,则结果是 NaN ;
  • 如果是 Infinity 减 Infinity ,则结果是 NaN ;
  • 如果是 -Infinity 减 -Infinity ,则结果是 NaN ;
  • 如果是 Infinity 减 -Infinity ,则结果是 Infinity ;
  • 如果是 -Infinity 减 Infinity ,则结果是 -Infinity ;
  • 如果是+0 减+0,则结果是0;
  • 如果是+0 减-0,则结果是0;
  • 如果是-0 减-0,则结果是0;
  • 如果有一个操作数是字符串、布尔值、 null 或 undefined ,则先在后台调用 Number() 函数将其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是 NaN ,则减法的结果就是 NaN ;
  • 如果有一个操作数是对象,则调用对象的 valueOf() 方法通过Number()以取得表示该对象的数值。如果对象没有 valueOf() 方法,则调用其 toString()方法通过Number()进行参数类型转换。
    var o={
        toString:function(){
            return "32";
        }
    };
    var temp1=132;
    alert(temp1-o); // 100
    var o={
        toString:function(){
            return 32; // 只想告诉你,toString不一定返回字符串。
        }
    };
    var temp1=132;
    alert(temp1-o); // 100
var result1 = 5 - true; // 4,因为 true 被转换成了 1
var result2 = NaN - 1; // NaN
var result3 = 5 - 3; // 2
var result4 = 5 - ""; // 5,因为"" 被转换成了 0
var result5 = 5 - "2"; // 3,因为"2"被转换成了 2
var result6 = 5 - null; // 5,因为 null 被转换成了 0

关系操作符

小于(<)、大于(>)、小于等于(<=)和大于等于(>=)这几个关系操作符用于对两个值进行比较,比较的规则与我们在数学课上所学的一样。这几个操作符都返回一个布尔值,如下面的例子所示:

var result1 = 5 > 3; //true
var result2 = 5 < 3; //false

与 ECMAScript中的其他操作符一样,当关系操作符的操作数使用了非数值时,也要进行数据转换或完成某些奇怪的操作。以下就是相应的规则。

  • 如果两个操作数都是数值,则执行数值比较。
  • 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
  • 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
  • 如果一个操作数是对象,则调用这个对象的 valueOf() 方法,用得到的结果按照前面的规则执行比较。如果对象没有 valueOf() 方法,则调用 toString() 方法,并用得到的结果根据前面的规则执行比较。
  • 如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。两个操作数是布尔值也是一个道理。
  • 如果一个是布尔值,另外一个是字符串。那么就会将字符串转换为数值进行比较。
  • 任何类型操作数与NaN、undefined比较都返回false,包括他们自身。因为undefined通过Number()类型转换后值为NaN,所以比较后就为false。

总结来说:比较方式分为两种,一种是数值比较,一种是字符编码大小比较。字符串编码大小比较必须满足两个操作数都是字符串时才会发生。只要两个操作数其中之一不是字符串都会根据数值比较。然而特殊条件是NaN,它不是一个数值,也没有字符编码大小,发生NaN跟任何数比较都是false。

    var temp1=‘-6‘;
    var temp2=‘-5‘;
    alert(temp1>temp2); // true 两个都是字符串,发生了字符编码大小比较
    var temp1=‘3‘;
    var temp2=‘23‘;
    alert(temp1>temp2); // true 
    alert(temp2>temp1); // false
    var temp1=3;
    var temp2=‘23‘;
    alert(temp1>temp2); // false 
    alert(temp2>temp1); // true

此时,字符串 “23” 会被转换成数值 23,然后再与 3 进行比较,因此就会得到合理的结果。在比较数值和字符串时,字符串都会被转换成数值,然后再以数值方式与另一个数值比较。当然,这个规则对前面的例子是适用的。可是,如果那个字符串不能被转换成一个合理的数值呢?比如:

var result = "a" < 3; // false,因为"a"被转换成了 NaN

由于字母 “a” 不能转换成合理的数值,因此就被转换成了 NaN 。根据规则,任何操作数与 NaN 进行关系比较,结果都是 false 。于是,就出现了下面这个有意思的现象:

    var temp1=123;
    var temp2=NaN;
    alert(temp1>temp2); // false NaN跟任何类型数比较都为false
    alert(temp2>=temp1); // false

按照常理,如果一个值不小于另一个值,则一定是大于或等于那个值。然而,在与 NaN 进行比较时,这两个比较操作的结果都返回了 false 。

    var temp1=true;
    var temp2=‘0‘;
    alert(temp1>temp2); // true true通过Number()变成了1,字符‘0‘通过Number()类型转换函数变成了
    var temp1=123;
    var temp2=null;
    alert(temp1>temp2); // true null被Number()类型转换函数转化为0了。
    alert(temp2>temp1); // false
    var temp1=‘a‘;
    var temp2=‘A‘;
    alert(temp1>temp2); // true 所有小写字母编码位于大写字母编码后,所以小写总是大于大写。
    alert(temp2>temp1); // false

相等操作符

确定两个变量是否相等是编程中的一个非常重要的操作。在比较字符串、数值和布尔值的相等性时,问题还比较简单。但在涉及到对象的比较时,问题就变得复杂了。最早的 ECMAScript 中的相等和不等操作符会在执行比较之前,先将对象转换成相似的类型。后来,有人提出了这种转换到底是否合理的质疑。最后,ECMAScript 的解决方案就是提供两组操作符:相等和不相等——先转换再比较,全等和不全等——仅比较而不转换。

相等和不相等

ECMAScript 中的相等操作符由两个等于号( == )表示,如果两个操作数相等,则返回 true 。而不相等操作符由叹号后跟等于号( != )表示,如果两个操作数不相等,则返回 true 。这两个操作符都会先转换操作数(通常称为强制转型),然后再比较它们的相等性。

在转换不同的数据类型时,相等和不相等操作符遵循下列基本规则:

  • 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值—— false 转换为 0,而true 转换为 1;
  • 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;
  • 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf() 方法,用得到的基本类型值按照前面的规则进行比较;如果没有valueOf()方法则调用toString()方法,用得到的基本类型值按照前面的规则进行比较,如果两个都没有,直接返回false。
    var ox={
        valueOf:function(){
            return 0;
        },
        toString:function(){
            return 0;
        }
    };
    alert("ox==0  :  "+(ox==0)); //true
    var ox={
        toString:function(){
            return 0;
        }
    };
    alert("ox==0  :  "+(ox==0)); //true
    var ox={

    };
    alert("ox==0  :  "+(ox==0)); //false

这两个操作符在进行比较时则要遵循下列规则:

  • null 和 undefined 是相等的。
  • 要比较相等性之前,不会自动将 null 和 undefined 转换成其他任何值。这是一个特例,但是>、>=、<、<=比较时,会自动转换
  • 如果有一个操作数是 NaN ,则相等操作符返回 false ,而不相等操作符返回 true 。重要提示:即使两个操作数都是 NaN ,相等操作符也返回 false ;因为按照规则, NaN 不等于 NaN 。
  • 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true ;否则,返回 false 。
    var o1=new Object();
    var o2=new Object();
    var o3=o1;

    alert(o1==o2); // 不指向同一个对象。
    alert(o2==o3);
    alert(o1==o3); // 指向同一个对象。

下表列出了一些特殊情况及比较结果:

技术分享

其中null和undefined与0进行相等比较时,都返回false,其原因是要比较相等性之前,不会自动将 null 和 undefined 转换成其他任何值。

    alert("null<1  :  "+(null<1)); // true , null被Number()转换成了0
    alert("null>1  :  "+(null>1)); // false
    alert("null==null  :  "+(null==null)); // true , nullnull相同。
    alert("null==0  :  "+(null==0));  // false , 在比较null0 时,却与第一个结论发生了矛盾。(第一个null,被自动转换了,但是这里如果发生自动转换结果应该是true)
    //其实底层有一个规定:要比较相等性之前,不会自动将 nullundefined 转换成其他任何值。这是一个特例,但是>、>=、<、<=比较时,会自动转换
alert(Number(null)==0); // true我们手动把null转换成 0 了。
alert(null != 0); //true
alert(true==‘1‘); // true

全等和不全等

除了在比较之前不转换操作数之外,全等和不全等操作符与相等和不相等操作符没有什么区别。全等操作符由 3 个等于号( === )表示,它只在两个操作数未经转换就相等的情况下返回 true ,如下面的例子所示:

var result1 = ("55" == 55); //true,因为转换后相等
var result2 = ("55" === 55); //false,因为不同的数据类型不相等

在这个例子中,第一个比较使用的是相等操作符比较字符串 “55” 和数值 55,结果返回了 true 。如前所述,这是因为字符串 “55” 先被转换成了数值 55,然后再与另一个数值 55 进行比较。第二个比较使用了全等操作符以不转换数值的方式比较同样的字符串和值。在不转换的情况下,字符串当然不等于数值,因此结果就是 false 。

不全等操作符由一个叹号后跟两个等于号( !== )表示,它在两个操作数未经转换就不相等的情况下返回 true 。例如:

var result1 = ("55" != 55); //false,因为转换后相等
var result2 = ("55" !== 55); //true,因为不同的数据类型不相等

在这个例子中,第一个比较使用了不相等操作符,而该操作符会将字符串 “55” 转换成 55,结果就与第二个操作数(也是 55)相等了。而由于这两个操作数被认为相等,因此就返回了 false 。第二个比较使用了不全等操作符。假如我们这样想:字符串 55 与数值 55 不相同吗?,那么答案一定是:是的( true )。

记住: null == undefined 会返回 true ,因为它们是类似的值;但 null === undefined 会返回 false ,因为它们是不同类型的值。

提示:由于相等和不相等操作符存在类型转换问题,而为了保持代码中数据类型的完整性,我们推荐使用全等和不全等操作符。

条件操作符

条件操作符应该算是 ECMAScript 中最灵活的一种操作符了,而且它遵循与 Java 中的条件操作符相同的语法形式,如下面的例子所示:

variable = boolean_expression ? true_value : false_value;
本质上,这行代码的含义就是基于对 boolean_expression 求值的结果,决定给变量 variable赋什么值。如果求值结果为 true ,则给变量 variable 赋 true_value 值;如果求值结果为 false ,则给变量 variable 赋 false_value 值。再看一个例子:
var max = (num1 > num2) ? num1 : num2;

在这个例子中, max 中将会保存一个最大的值。这个表达式的意思是:如果 num1 大于 num2 (关系表达式返回 true ),则将 num1 的值赋给 max ;如果 num1 小于或等于 num2 (关系表达式返回 false ),则将 num2 的值赋给 max 。

赋值操作符

简单的赋值操作符由等于号( = )表示,其作用就是把右侧的值赋给左侧的变量,如下面的例子所示:

var num = 10;

略。。。详情请看《JavaScript高级程序设计》 p71。

逗号操作符

使用逗号操作符可以在一条语句中执行多个操作,如下面的例子所示:

var num1=1, num2=true, num3=‘JavaScript‘;

逗号操作符多用于声明多个变量;但除此之外,逗号操作符还可以用于赋值。在用于赋值时,逗号操作符总会返回表达式中的最后一项,如下面的例子所示:

var num = (5, 1, 4, 8, 0); // num 的值为 0

由于 0 是表达式中的最后一项,因此 num 的值就是 0。虽然逗号的这种使用方式并不常见,但这个例子可以帮我们理解逗号的这种行为。

语句

ECMA-262 规定了一组语句(也称为流控制语句)。从本质上看,语句定义了 ECMAScript 中的主要语法,语句通常使用一或多个关键字来完成给定任务。语句可以很简单,例如通知函数退出;也可以比较复杂,例如指定重复执行某个命令的次数。

if 语句

大多数编程语言中最为常用的一个语句就是 if 语句。以下是 if 语句的语法:

if (condition) statement1 else statement2

其中的 condition(条件)可以是任意表达式;而且对这个表达式求值的结果不一定是布尔值。ECMAScript 会自动调用 Boolean() 转换函数将这个表达式的结果转换为一个布尔值。如果对 condition求值的结果是 true ,则执行statement1 (语句1),如果对condition求值的结果是 false ,则执行statement2(语句 2)。而且这两个语句既可以是一行代码,也可以是一个代码块(以一对花括号括起来的多行代码)。请看下面的例子。

if (i > 25)
    alert("Greater than 25."); // 单行语句
else {
    alert("Less than or equal to 25."); // 代码块中的语句
}

不过,业界普遍推崇的最佳实践是始终使用代码块,即使要执行的只有一行代码。因为这样可以消除人们的误解,否则可能让人分不清在不同条件下要执行哪些语句。

另外,也可以像下面这样把整个 if 语句写在一行代码中:

if (condition1) statement1 else if (condition2) statement2 else statement3

但我们推荐的做法则是像下面这样:

if (i > 25) {
    alert("Greater than 25.");
} else if (i < 0) {
    alert("Less than 0.");
} else {
    alert("Between 0 and 25, inclusive.");
}

for 语句

for 语句也是一种前测试循环语句,但它具有在执行循环之前初始化变量和定义循环后要执行的代码的能力。以下是 for 语句的语法:

for (initialization; expression; post-loop-expression) statement

下面是一个示例:

var count = 10;
for (var i = 0; i < count; i++){
    alert(i);
}

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

var count = 10;
for (var i = 0; i < count; i++){
    alert(i);
}
alert(i); //10

在ECMAScript中,只存在function函数作用域。其它作用域不存在!!多个script标签能够共享成员变量。

在这个例子中,会有一个警告框显示循环完成后变量 i 的值,这个值是 10。这是因为,即使 i 是在循环内部定义的一个变量,但在循环外部仍然可以访问到它。

此外, for 语句中的初始化表达式、控制表达式和循环后表达式都是可选的。将这三个表达式全部省略,就会创建一个无限循环,例如:

for (;;) { // 无限循环
    doSomething();
}

而只给出控制表达式实际上就把 for 循环转换成了 while 循环,例如:

var count = 10;
var i = 0;
for (; i < count; ){
    alert(i);
    i++;
}

由于 for 语句存在极大的灵活性,因此它也是 ECMAScript 中最常用的一个语句。

for-in 语句

for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。以下是 for-in 语句的语法:

for (property in expression) statement

下面是一个示例:

var ox={
    property1:"这是一个对象",
    functionDescript:"我们要遍历这个对象里面的属性",
    valueOf:function(){
        return "这是valueOf()方法";
    }
};

for(var propertyItem in ox){//这里的var可以去掉,让 propertyItem 变成全局变量。
    alert(propertyItem);
}

在这个例子中,我们使用 for-in 循环来显示了 自定义 对象的所有属性。每次执行循环时,都会将 自定义 对象中存在的一个属性名赋值给变量propertyItem 。这个过程会一直持续到对象中的所有属性都被枚举一遍为止。与 for 语句类似,这里控制语句中的 var 操作符也不是必需的。但是,为了保证使用局部变量,我们推荐上面例子中的这种做法。

ECMAScript 对象的属性没有顺序。因此,通过 for-in 循环输出的属性名的顺序是不可预测的。具体来讲,所有属性都会被返回一次,但返回的先后次序可能会因浏览器而异。

但是,如果表示要迭代的对象的变量值为 null 或 undefined 或 NaN, for-in 语句会抛出错误。ECMAScript 5 更正了这一行为;对这种情况不再抛出错误,而只是不执行循环体。为了保证最大限度的兼容性,建议在使用 for-in 循环之前,先检测确认该对象的值不是 null 或 undefined 或 NaN。

for(propertyItem in null){
    alert(propertyItem);
}

for(propertyItem in undefined){
    alert(propertyItem);
}

for(propertyItem in NaN){
    alert(propertyItem);
}

alert(123); // 输出123 , 说明最终执行到了这里。
提示:Safari 3 以前版本的 for-in 语句中存在一个 bug,该 bug 会导致某些属性被返回两次。

label 语句

使用 label 语句可以在代码中添加标签,以便将来使用。以下是 label 语句的语法:

label: statement

下面是一个示例:

start: for (var i=0; i < count; i++) {
    alert(i);
}

这个例子中定义的 start 标签必须在将来由 break 或 continue 语句引用。加标签的语句必须与 for 语句等循环语句配合使用。

break 和 continue 语句都可以与 label 语句联合使用,从而返回代码中特定的位置。这种联合使用的情况多发生在循环嵌套的情况下,如下面的例子所示:

var num = 0;
outermost:
for (var i=0; i < 10; i++) {
    for (var j=0; j < 10; j++) {
        if (i == 5 && j == 5) {
            break outermost;
        }
        num++;
    }
}
alert(num); //55

在这个例子中, outermost 标签表示外部的 for 语句。如果每个循环正常执行 10 次,则 num++语句就会正常执行 100 次。换句话说,如果两个循环都自然结束, num 的值应该是 100。但内部循环中的 break 语句带了一个参数:要返回到的标签。添加这个标签的结果将导致 break 语句不仅会退出内部的 for 语句(即使用变量 j 的循环),而且也会退出外部的 for 语句(即使用变量 i 的循环)。为此,当变量 i 和 j 都等于 5 时, num 的值正好是 55。同样, continue 语句也可以像这样与 label 语句联用,如下面的例子所示:

var num = 0;
outermost:
for (var i=0; i < 10; i++) {
    for (var j=0; j < 10; j++) {
        if (i == 5 && j == 5) {
            continue outermost;
        }
        num++;
    }
}
alert(num); //95

在这种情况下, continue 语句会强制继续执行循环——退出内部循环,执行外部循环。当 j 是 5时, continue 语句执行,而这也就意味着内部循环少执行了 5 次,因此 num 的结果是 95。

虽然联用 break 、 continue 和 label 语句能够执行复杂的操作,但如果使用过度,也会给调试带来麻烦。在此,我们建议如果使用 label 语句,一定要使用描述性的标签,同时不要嵌套过多的循环。

with 语句

with 语句的作用是将代码的作用域设置到一个特定的对象中。 with 语句的语法如下:

with (expression) statement;

定义 with 语句的目的主要是为了简化多次编写同一个对象的工作,如下面的例子所示:

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 语句的代码块内部,限定了一个特殊的作用域(该作用域和function的作用域不同),当在with作用域里面查找属性时,首先从location对象里面查找,如果location里面没有该属性,才从全局变量里面查找。

为了更好理解上面这段话,我们看看下面的例子:

var ox={
    property1:"这是一个对象",
    functionDescript:"我们要遍历这个对象里面的属性",
    valueOf:function(){
        return "这是valueOf()方法";
    }
};
var ooname=‘positive‘;
var property1=‘哈哈哈‘;

with(ox){
    var name=‘lang‘; //在with内部定义的变量,在with外部也能够访问。


    alert(property1); // 这是一个对象
    alert(ooname);  // positive

    var ooname=‘nagetive‘; //在with内部定义的变量,却修改了外部的ooname值。
    alert(ooname); // nagetive
}

alert(name); // lang
alert(ooname); // nagetive
alert(property1); // 哈哈哈

总结:在with内部定义的变量是相对全局变量(如果with在function里面,则with中定义的变量为function的局部变量,如果with在script标签中使用则为script全局变量,前提是定义变量时通过var定义,如果没有var则是script全局变量)。with的作用只是对取属性时,查找属性顺序有了改变而已,先查找with关联的对象里面是否有该属性,再查找全局变量。如果with在function里面使用时,查找顺序为:关联对象—>function局部变量—>script全局变量。

严格模式下不允许使用 with 语句,否则将视为语法错误。

提示:由于大量使用 with 语句会导致性能下降,同时也会给调试代码造成困难,因此在开发大型应用程序时,不建议使用 with 语句

switch 语句

switch 语句与 if 语句的关系最为密切,而且也是在其他语言中普遍使用的一种流控制语句。ECMAScript 中 switch 语句的语法与其他基于 C 的语言非常接近,如下所示:

switch (expression) {
    case value: statement
        break;
    case value: statement
        break;
    case value: statement
        break;
    case value: statement
        break;
    default: statement
}

switch 语句中的每一种情形(case)的含义是:“如果表达式等于这个值(value),则执行后面的语句(statement)”。而 break 关键字会导致代码执行流跳出 switch 语句。如果省略 break 关键字,就会导致执行完当前 case 后,继续执行下一个 case。最后的 default 关键字则用于在表达式不匹配前面任何一种情形的时候,执行机动代码(因此,也相当于一个 else 语句)。

从根本上讲, switch 语句就是为了让开发人员免于编写像下面这样的代码:

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");
}

通过为每个 case 后面都添加一个 break 语句,就可以避免同时执行多个 case代码的情况。假如确实需要混合几种情形,不要忘了在代码中添加注释,说明你是有意省略了 break 关键字,如下所示:

switch (i) {
    case 25:
    /*  合并两种情形 */
    case 35:
        alert("25 or 35");
        break;
    case 45:
        alert("45");
        break;
    default:
        alert("Other");
}

虽然 ECMAScript 中的 switch 语句借鉴自其他语言,但这个语句也有自己的特色。首先,可以在switch 语句中使用任何数据类型(在很多其他语言中只能使用数值,当然Java高版本中能够用字符串等),无论是字符串,还是对象都没有问题。其次,每个 case 的值不一定是常量,可以是变量,甚至是表达式。请看下面这个例子:

switch ("hello world") {
    case "hello" + " world":
        alert("Greeting was found.");
        break;
    case "goodbye":
        alert("Closing was found.");
        break;
    default:
        alert("Unexpected message was found.");
}

在这个例子中, switch 语句使用的就是字符串。其中,第一种情形实际上是一个对字符串拼接操作求值的表达式。由于这个字符串拼接表达式的结果与 switch 的参数相等,因此结果就会显示”Greeting was found.” 。而且,使用表达式作为 case 值还可以实现下列操作:

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.");
}

这个例子首先在 switch 语句外面声明了变量 num 。而之所以给 switch 语句传递表达式 true ,是因为每个 case 值都可以返回一个布尔值。这样,每个 case 按照顺序被求值,直到找到匹配的值或者遇到 default 语句为止(这正是这个例子的最终结果)。

提示:switch 语句在比较值时使用的是全等操作符,因此不会发生类型转换(例如,
字符串 "10" 不等于数值 10)。
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    JavaScript基本概念(二)