JavaScript入门教程

JavaScript简介
JavaScript语法基础
JavaScript流程控制
JavaScript函数
面向对象编程
JavaScript事件
JavaScript DOM
正则表达式
JavaScript BOM
AJAX

专题分析

浏览器兼容性
JS优化
Web前端开发规范
编辑器推荐
总结和笔记

学习助手

对象参考手册
ECMAScript分析
数据中心
QQ交流群

JS函数的创建与参数

创建JS函数

创建 JavaScript 函数的一种不长用的方式(几乎没有人用)是通过 new 操作符来作用于 Function“构造器”:
    var funcName = new Function( [argname1, [... argnameN,]] body );
参数列表中可以有任意多的参数,然后紧跟着是函数体,比如:
    var add = new Function("x", "y", "return(x+y)");
    print(add(2, 4));

将会打印结果:
    6

但是,谁会用如此难用的方式来创建一个函数呢?如果函数体比较复杂,那拼接这个 String要花费很大的力气,所以 JavaScript 提供了一种语法糖,即通过字面量来创建函数:
    function add(x, y){
        return x + y;
    }
或:
    var add = function(x, y){
        return x + y;
    }

事实上,这样的语法糖更容易使传统领域的程序员产生误解, function 关键字会调用Function 来 new 一个对象,并将参数表和函数体准确的传递给 Function 的构造器。

通常来说,在全局作用域(作用域将在下一节详细介绍)内声明一个对象,只不过是对一个属性赋值而已,比如上例中的 add 函数,事实上只是为全局对象添加了一个属性,属性名为add,而属性的值是一个对象,即 function(x, y){return x+y;},理解这一点很重要,这条语句在语法上跟:
    var str = "This is a string";
并无二致。都是给全局对象动态的增加一个新的属性,如此而已。

为了说明函数跟其他的对象一样,都是作为一个独立的对象而存在于 JavaScript 的运行系统,我们不妨看这样一个例子:
function p(){
    print("invoke p by ()");
}
p.id = "func";
p.type = "function";
print(p);
print(p.id+":"+p.type);
print(p());

没有错,p 虽然引用了一个匿名函数(对象),但是同时又可以拥有属性,完全跟其他对象一样,运行结果如下:
function (){
    print("invoke p by ()");
}
func:function
invoke p by ()

JS函数的参数

在 JavaScript 中,函数的参数是比较有意思的,比如,你可以将任意多的参数传递给一个函数,即使这个函数声明时并未制定形式参数,比如:
function adPrint(str, len, option){
    var s = str || "default";
    var l = len || s.length;
    var o = option || "i";
    s = s.substring(0, l);
    switch(o){
        case "u":
            s = s.toUpperCase();
            break;
        case "l":
            s = s.toLowerCase();
            break;
        default:
            break;
    }
    print(s);
}
adPrint("Hello, world");
adPrint("Hello, world", 5);
adPrint("Hello, world", 5, "l");//lower case
adPrint("Hello, world", 5, "u");//upper case

函数 adPrint 在声明时接受三个形式参数:要打印的串,要打印的长度,是否转换为大小写的标记。但是在调用的时候,我们可以按顺序传递给 adPrint 一个参数,两个参数,或者三个参数(甚至可以传递给它多于 3 个,没有关系),运行结果如下:
Hello, world
Hello
hello
HELLO

事实上,JavaScript 在处理函数的参数时,与其他编译型的语言不一样,解释器传递给函数的是一个类似于数组的内部值,叫 arguments,这个在函数对象生成的时候就被初始化了。比如我们传递给 adPrint 一个参数的情况下,其他两个参数分别为 undefined.这样,我们可以才 adPrint 函数内部处理那些 undefined 参数,从而可以向外部公开:我们可以处理任意参数。

我们通过另一个例子来讨论这个神奇的 arguments:
function sum(){
    var result = 0;
    for(var i = 0, len = arguments.length; i < len; i++){
        var current = arguments[i];
        if(isNaN(current)){
            throw new Error("not a number exception");
        }else{
            result += current;
        }
    }
    return result;
}
print(sum(10, 20, 30, 40, 50));
print(sum(4, 8, 15, 16, 23, 42));//《迷失》上那串神奇的数字
print(sum("new"));

函数 sum 没有显式的形参,而我们又可以动态的传递给其任意多的参数,那么,如何在 sum函数中如何引用这些参数呢?这里就需要用到 arguments 这个伪数组了,运行结果如下:
150
108
Error: not a number exception