《高级程序设计》 3.6 语句和函数

一、语句

1、if语句

if (condition) statement1 else statement2

其中condition(条件)可以是任意表达式;而且对这个表达式求值的结果不一定是布尔值。javascript会自动调用Boolean()转换函数将这个表达式的结果转换为一个布尔值。如果对condition的求值结果是true,则执行statement1(语句1),如果对condition求值的结果是false,则执行statement2(语句2)。

推荐,使用代码块,即使要执行的只有一行代码。

2、do-while语句

do-while语句是一种后测试循环语句(注意是循环语句,if不是循环语句),即只有在循环体中的代码执行之后,才会测试出口条件。换句话说,在对条件表达式求值之前,循环体内的代码至少会被执行一次。

do{

  statement

}while(expression);

像do-while这种后测试循环语句最常用于循环体中的代码至少要被执行一次的情形。

3、while语句

while语句属于前测试循环语句,也就是说,在循环体内的代码被执行之前,就会对出口条件求值。因此,循环体内的代码有可能永远不会被执行。

while(expression) statement

    var i=0;
    do{
        i+=2;
    }while(i<10);
//    对比
    var j=0;
    while(j<10){
        j+=2;
    }

4、for语句

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

与while循环的区别是,for循环只是把循环有关的代码集中在了一个位置。

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

    var count=10;
    for(var i=0;i<count;i++){
        alert(i);
    }
    alert("i的值为"+i);  //在循环内部定义的变量,循环外部仍然可以访问到
    
    for(;;){  //无限循环
        //doSomething();
    }
    //以下代码相当于while循环
    var count1=10;
    var j=0;
    for(;j<count;){
        alert(j);
        j++;
    }

5、for-in语句

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

for (property in expression) statement

for(var propName in window){
        document.write(propName);
    }
    //每次执行循环时,都会将window对象中存在的一个属性名赋值给变量propName。这个过程会一直持续到对象中的所有属性都被枚举一遍为止。

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

6、label语句

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

label:statement

start:for (var i = 0; i < count; i++) {
        alert(i);
}
//start标签可以在将来由break或continue语句引用。加标签的语句一般都要与for语句等循环语句配合使用

7、break和continue语句

break和continue语句用于在循环中精确地控制代码的执行。其中,break语句会立即退出循环强制继续执行循环后面的语句。而continue语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行。

//        1、break语句
//        var num = 0;
//        for (var i = 1; i < 10; i++) {
//            if (i % 5 == 0) {
//                break;  //当i=5的时候,执行break语句退出循环,循环总共执行了4次
//            }
//            num++;
//        }
//        alert(num); //4
//        2、continue语句
//        var num=0;
//        for(var i=1;i<10;i++){
//            if(i%5==0){
//                continue; //当i=5的时候,执行continue语句,跳过num++,继续下一次i=6的循环。总共循环应该是9次,跳过一次,所以循环8次
//            }
//            num++;
//        }
//        alert(num); //8
//        break和continue语句都可以与label语句联合,多发生在循环嵌套的情况下
//        3、break和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
//        如果每个循环正常执行10次,则num++的语句就会正常执行100次。当i和j的值都等于5时,num的值正好是55;
//        4、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
//        本来执行次数是100次,当i==5,j==5的时候continue,跳过后面的j循环,继续i==6的循环

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

8、with语句

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

with (expression)  statement;

    //    var qs=location.search.substring(1);
    //    var hostName=location.hostname;
    //    var url=location.href;
    //    上面几行代码使用with语句
    with (location) {
        var qs = search.substring(1);
        var hostName = hostName;
        var url = href;
    }
//    使用with语句关联了location对象,在with语句的代码块内部,每个变量首先被认为是一个局部变量,
// 而如果在局部环境中找不到该变量的定义,就会查询location对象中是否有同名属性。如果发现了同名属性,则以location对象属性的值作为变量的值

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

9、switch语句

switch语句和if语句的关系最为密切,而且也是在其他语言中普遍使用的一种流控制语句。语法:

 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语句)

        var i = 45;
//     if(i==25){
//         alert("25");
//     }else if(i==35){
//         alert("35");
//     }else if(i==45){
//         alert("45");
//     }else{
//         alert("other");
//     }
////     等价于
//        switch (i) {
//            case 25:
//                alert("25");
//                break;
//            case 35:
//                alert("35");
//                break;
//            case 45:
//                alert("45");
//                break;
//            default:
//                alert("other");
//        }
//        通过为每个case后面都添加一个break语句,就可以避免同时执行多个case代码的情况。假如确实需要混合几种情形,不要忘了在代码中添加注释
        switch (i){
            case 25:
//                合并两种情形
            case 35:
                alert("25 or 35");
                break;
            case 45:
                alert("45");
                break;
            default:
                alert("other");
        }

可以在switch语句中使用任何数据类型(在很多其他语言中只能使用数值),无论是字符串,还是对象都没有问题。

每个case的值不一定是常量,可以是变量,甚至是表达式

//        switch ("helloworld"){
//            case "hello"+"world":
//                alert("Greeting was found");
//                break;
//            case "goodbye":
//                alert("Closing was found");
//                break;
//            default:
//                alert("Unexpected 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.");
        }

注意:switch语句在比较值时使用的是全等操作符,因此不会发生类型转换。

二、函数

javascript中的函数使用function关键字来声明,后跟一组参数以及函数体。语法:

function functionName(arg0,arg1,...,argN){
        statements
    }

位于return语句之后的任何代码都永远不会执行。

另外,return语句也可以不带有任何返回值。在这种情况下,函数在停止执行后将返回undefined值。这种用法一般用在需要提前停止函数执行而又不需要返回值的情况下。

严格模式对函数有一些限制:

  • 不能把函数命名为eval或arguments;
  • 不能把参数命名为eval或arguments;
  • 不能出现两个命名参数同名的情况。

如果出现以上情况,就会导致语法错误,代码无法执行。

理解参数

1)javascript函数不介意传递进来多少个参数,也不在乎传进来的参数是什么类型。也就是说,即便定义的函数只接受两个参数,调用的时候未必一定要传递两个参数。即,javascript函数的一个重要特点是:命名的参数只提供便利,但不是必需的。

2)在函数体,可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。通过访问arguments对象的length属性可以获知有多少个参数传递给了函数。

3)arguments可以与命名参数一起使用。

4)arguments的值永远与对应命名参数的值保持同步。

    $(function(){
////        1)
//        sayHi("Lily","How are you!");   //HelloLilyHow are you!
////        2)
//        howManyArgs("string",45); //2
//        howManyArgs(); //0
//        howManyArgs(12);  //1
//        doAdd(40);
//        doAdd(40,30);
        doAdd1(5,5); //15
        doAdd1(5); //NaN
    });
//    1)
//    function sayHi(){
//        alert("Hello"+arguments[0]+arguments[1]);
//    }
//    2)
//    function howManyArgs(){
//        alert(arguments.length);
//    }
//    3)
//    function doAdd(num1,num2){
//        if(arguments.length==1){
//            alert(num1+10);
//        }else if(arguments.length==2){
//            alert(arguments[0]+num2);
//        }
//    }
//    4)
    function doAdd1(num1,num2){
        arguments[1]=10;
        alert(arguments[0]+num2);
    }
//    每次执行都会重写第二个参数,将第二个参数的值修改为10。
//    arguments对象的值跟对应命名参数,它们的内存空间是独立的,但它们的值会同步。但这种影响是单向的:修改命名参数不会改变arguments中对应的值。
//    如果只传了一个参数,arguments[1]设置的值不会反应到命名参数中。arguments对象的长度由传入的参数个数决定。
//    没有传递值的命名参数将自动被赋予undefined值。这就跟变量没有初始化一样。
//    严格模式,即使像上例4)把arguments[1]设置为10,num2的值仍然是undefined。其次,重写arguments的值会导致语法错误(代码将不会执行)

javascript中的所有参数传递的都是值,不可能通过引用传递参数。

没有重载:

javascript不能像传统意义上的那样实现重载。如果函数被定义了两次,后定义的函数会覆盖了先定义的函数。

javascript中没有函数签名的慨念,因为其函数参数是以一个包含零或多个值的数组的形式传递的。由于不存在函数签名的特性,javascript函数不能重载。

原文地址:https://www.cnblogs.com/zhaojieln/p/4281103.html