【读书笔记】JavaScript高级编程(四)

书中第3章 基本概念摘要(三) express

3.6 语句

3.6.1 if 语句
if(condition) statement1 else statement2

3.6.2 do-while 语句
do{
    statement
}while(expression)

3.6.3 while 语句
while(expression) statement

3.6.4 for 语句
for(initialization; expression; post-loop-expression) statement

在for循环的变量初始化表达式中,也能够不使用var关键字。该变量的初始化能够在外部执行,例如:
    var count = 10;
    var i;
    for(i=0;i<count;i++){
        alert(i);
    }
以上代码与在循环初始化表达式中声明变量的效果是同样的。因为ECMAScript中不存在块级做用域,所以在循环内部定义的变量也能够在外部访问到。例如:
    var count = 10;
    for(var i=0;i<count;i++){
        alert(i);
    }
    alert(i);   //10
在这个例子中,会有一个警告框显示循环完成后变量 i 的值,这个值是10。这是由于,即便 i 是在循环内部定义的一个变量,但在循环外部仍然能够访问到它。

3.6.5 for-in 语句
for-in 语句是一种精准的迭代语句,能够用来枚举对象的属性。
    for(property in expression) statement
示例:
    for(var propName in window){
        document.write(propName);
        document.write('<br/>');
    }
ECMAScript对象的属性没有顺序,所以,经过for-in循环输出的属性名的顺序是不可预测的。具体来说,因此属性都会被返回一次,但返回的前后次序可能会因浏览器而异。(Safari3 之前版本的for-in语句中存在一个bug,该bug会致使某些属性被返回两次)

3.6.6 label语句
label: statement
示例:
    start: for(var i=0;i<count;i++){
        alert(i);
    }
这个例子中定义的start标签能够在未来由break或continue语句引用。加标签的语句通常都要与for语句等循环语句配合使用。


3.6.7 break 和 continue 语句
break语句示例:
    var num = 0;
    for(var i=1;i<10;i++){
        if(i%5==0){
            break;
        }
        num++;
    }
    alert(num); //4


continue语句示例:
    var num = 0;
    for(var i=1;i<10;i++){
    if(i%5==0){
        continue;
    }
    num++;
    }
    alert(num); //8


break语句结合label语句联合使用:
    var num = 0;
    outermost:
    for(var i=1;i<10;i++){
        for(var j=0;j<10;j++){
            if(i==5 && j==5){
                break outermost;
            }
            num++;
        }
    }
    alert(num); //55


continue语句结合label语句联合使用:
    var num = 0;

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


3.6.8 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语句的代码块内部,每一个变量首先被认为是一个局部变量,而若是在局部环境中找不到该变量的定义,就会查询location对象中是否有同名的属性。若是发现了同名属性,则以location对象属性的值做为变量的值。(因为大量使用with语句会致使性能降低,同时也会给调试代码速成困难,所以在开发大型应用程序时,不建议使用with语句)

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


ECMAScript中的switch语句借鉴自其它语言,但这个语句也有本身的特点。首先,能够在switch语句中使用任何数据类型(在不少其它语言中只能使用数值或枚举),不管是字符串,仍是对象都没有问题。其次,每一个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.")
    }
结果显示:Greeting 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.")
    }
结果显示:More than 20.

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

switch语句在比较值时使用的是全等操做符,所以不会发生类型转换(例如,字符串"10"不等于数值10)。


3.7 函数
函数的基本语法:
    function functionName(arg0, arg1, ..., argN){
        statements
    }
示例:
    function sayHi(name, message){
        alert("Hello " + name + "," + message);
    }
调用sayHi()函数的代码以下:
sayHi("Nicholas", "how are you today?");
输出结果是"Hello Nicholas,how are you today?".

3.7.1 理解参数
ECMAScript函数的参数与大多数其余语言中函数的参数有所不一样。ECMAScript函数不介意传递进来多少个参数,也不在意传进来参数是什么数据类型。由于ECMAScript中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(若是有参数的话)。若是这个数组中不包含任何元素,无所谓;若是包含多个元素,也没用问题。实际上,在函数体内能够经过arguments对象来访问这个参数数组,从而得到传递给函数的每个参数。
其实,arguments对象只是与数组相似(它并非Array的实例)。由于可使用方括号语法访问它的每个元素(即第一个元素是arguments[0],第二个元素是arguments[1],以此类推),使用length属性来肯定传递进来多少个参数。
上面的sayHi()函数也能够像下面这样重写,即不显示地使用命名参数:
    function sayHi(){
        alert("Hello " + arguments[0] + "," + arguments[1]);
    }
这个事实说明了ECMAScript函数的一个重要特色:命名的参数只提供便利,但不是必需的。

    function howManyArgs(){
        alert(arguments.length);
    }

    howManyArgs("string", 45); //2
    howManyArgs(); //0
    howManyArgs(12); //1


因而可知,开发人员能够利用这一点让函数可以接收任意个参数并分别实现适当的功能。例如:
    function doAdd(){
        if(arguments.length == 1){
            alert(arguments[0] + 10);
        }else if(arguments.length == 2){
            alert(arguments[0] + arguments[1]);
        }
    }

    doAdd(10);   //20
    doAdd(30, 20);   //50


另外一个与参数相关的重要方面,就是arguments对象能够与命名参数一块儿使用,例如:
    function doAdd(num1, num2){
        if(arguments.length == 1){
            alert(num1 + 10);
        }else if(arguments.length == 2){
            alert(arguments[0] + num2);
        }
    }

    doAdd(10);   //20
    doAdd(30, 20);   //50


关于参数还要记住最后一点:没有传递值的命名参数将自动被赋予undefined值。这就跟定义了变量但又没有初始化同样。例如,若是只给doAdd()函数传递了一个参数,则num2中就会保存undefined值。(ECMAScript中的全部参数传递的都是值,不可能经过引用传递参数)


3.7.2 没有重载
ECMAScript函数没有签名,由于其参数是由包含零或多个值的数组来表示的。而没有函数签名,真正的重载是不可能作到的。示例:
    function addSomeNumber(num){
        return num + 100;
    }

    function addSomeNumber(num){
        return num + 200;
    }

    var result = addSomeNumber(100);   
    alert(result);   //300
在此,addSomeNumber()被定义了两次,后定义的函数覆盖了先定义的函数。

如前所述,经过检查传入函数中参数的类型和数量并做出不一样的反应,能够模仿方法的重载.

浏览器

以上全部内容均摘自图书《JavaScript 高级程序设计(第2版)》[美] Nicholas C.Zakas 著 李松峰 曹力 译
函数

相关文章
相关标签/搜索