函数

  JavaScript是一种基于对象的脚本语言,JavaScript代码复用的单位是函数,但它的函数比结构化程序设计语言的函数功能更丰富。JavaScript语言中的函数就是“一等公民”,它可以独立存在;而且JavaScript的函数完全可以作为一个类使用(而且它还是该类唯一的构造器);与此同时,函数本身也是一个对象,函数本身是Function实例。JavaScript函数的功能非常丰富,如果想深入学习JavaScript,那就必须认真学习JavaScript函数。

定义函数的3种方式

  JavaScript是弱类型语言,因此定义函数时,既不需要声明函数的返回值类型,也不需要声明函数的参数类型。JavaScript目前支持3种函数定义方式。

定义命名函数

  定义命名函数的语法格式如下:

function functionName(parameter-list)  
{
    statements
}
注意

  在同一个<script.../>元素中时,JavaScript允许先调用函数,然后再定义该函数;但在不同的<script.../>元素中时,必须先定义函数,再调用该函数。也就是说,在后面的<script.../>元素中可以调用前面<script.../>里定义的函数。
  函数可以有返回值,也可以没有返回值。函数的返回值使用return语句返回,在函数的运行过程中,一旦遇到第一条return语句,函数就返回返回值,函数运行结束。

例子
<script type="text/javascript">  
    // 定义函数hello
    function hello(name)
    {
        // 如果参数类型为字符串,则返回静态字符串
        if (typeof name == 'string')
        {
            return name + ",你好";
        }
        // 当参数类型不是字符串时,执行此处的返回语句
        return '名字只能为字符串'
    }
    alert(hello('yeeku'));
</script>  

定义匿名函数

  JavaScript提供了定义匿名函数的方式,这种创建匿名函数的语法格式如下:

function(parameter-list)  
{
    statements
}

  这种函数定义语法无须指定函数名,而是将参数列表紧跟function关键字。在函数定义语法的最后不要忘记紧跟分号(;)。
  当通过这种语法格式定义了函数之后,实际上就是定义了一个函数对象(即Function实例),接下来可以将这个对象赋给另一个变量。
  对于这种匿名函数的语法,可读性非常好:程序使用function关键字定义一个函数对象(Function类的实例),然后把这个对象赋值给f变量,以后程序即可通过f来调用这个函数。

例子
<script type="text/javascript">  
    var f = function(name)
    {
        document.writeln('匿名函数<br />');
        document.writeln('你好' + name);
    };
    f('yeeku');
</script>  

使用Function类匿名函数

  JavaScript提供了一个Function类,该类也可以用于定义函数,Function类的构造器的参数个数可以不受限制,Function可以接受一系列的字符串参数,其中最后一个字符串参数是函数的执行体,执行体的各语句以分号(;)隔开,而前面的各字符串参数则是函数的参数。看下面定义函数的方式。

例子
<script type="text/javascript">  
    // 定义匿名函数,并将函数赋给变量f
    var f = new Function('name' ,
        "document.writeln('Function定义的函数<br />');"
        + "document.writeln('你好' + name);");
    // 通过变量调用匿名函数
    f('yeeku');
</script>  

递归函数

  递归函数是一种特殊的函数,递归函数允许在函数定义中调用函数本身。考虑对于如下计算:

n!=n*(n-1)*(n-2)*...*1  

  注意到等式左边需要求n的阶乘,而等式右边则是求n −1的阶乘。实质都是一个函数,因此可将求阶乘的函数定义如下。

例子
<script type="text/javascript">  
    // 定义求阶乘的函数
    function factorial(n)
    {
        // 如果n的类型是数值,才执行函数
        if (typeof(n) == "number" && n > 0)
        {
            // 当n等于1时,直接返回1
            if (n == 1) 
            {
                return 1;
            }
            // 当n不等于1时,通过递归返回值。
            else
            {
                return n * factorial(n - 1);
            }
        }
        // 当参数不是数值时,直接返回
        else
        {
            alert("参数类型不对!");
        }
    }
    // 调用阶乘函数
    alert(factorial(5));
</script>  

局部变量和局部函数

  前面已经介绍了局部变量的概念,在函数里定义的变量称为局部变量,在函数外定义的变量则称为全局变量,如果局部变量和全局变量的变量名相同,则局部变量会覆盖全局变量。局部变量只能在函数里访问,而全局变量可以在所有的函数里访问。
  与此类似的概念是局部函数,局部变量在函数里定义,而局部函数也在函数里定义。下面代码在函数outer中定义了两个局部函数。

例子
<script type="text/javascript">  
    // 定义全局函数
    function outer()
    {
        // 定义第一个局部函数
        function inner1()
        {
            document.write("局部函数11111<br />");
        }
        // 定义第二个局部函数
        function inner2()
        {
            document.write("局部函数22222<br />");  
        }
        document.write("开始测试局部函数...<br />");
        // 在函数中调用第一个局部函数
        inner1();
        // 在函数中调用第二个局部函数
        inner2();
        document.write("结束测试局部函数...<br />");
    }
    document.write("调用outer之前...<br />");
    // 调用全局函数
    outer();
    document.write("调用outer之后...<br />");
</script>  

  在上面代码中,在outer函数中定义了两个局部函数:inner1和inner2,并在outer函数内调用了这两个局部函数。因为这两个函数是在outer内定义的,因此可以在outer内访问它们。在outer外,则无法访问它们——也就是说,inner1、inner2两个函数仅在outer函数内有效。

注:本博客内容节选自李刚编著的疯狂HTML 5/CSS 3/JavaScript讲义 ,详细内容请参阅书籍。