JavaScript+jQuery前端开发基础教程(微课版)
上QQ阅读APP看书,第一时间看更新

3.2 函数

当某一段代码需要重复使用,或者需要对批量数据执行相同操作时,就可使用函数来完成。

了解函数的用途

3.2.1 定义函数

定义函数

1. 函数的语句定义方法

JavaScript用function关键字来声明函数,基本语法格式如下。

function 函数名([参数1 , 参数2 , …]){
      代码块
      [return 返回值]
}

在当前脚本中,函数名应该是唯一的。函数参数是可选的。多个参数之间用逗号分隔。大括号中的代码块称为函数体。在函数体中或在函数末尾,可使用return语句指定函数返回值。返回值可以是任意的常量、变量或者表达式。

例如,下面的函数用于计算两个数的和。

function sum(a, b) {
    return a + b
}

2. 在表达式中定义函数

JavaScript允许在表达式中定义函数。例如,在表达式中定义求和函数。

var sum2 = function (a, b) {
    return a + b
}

3. 使用Function构造函数

在JavaScript中,函数也是一种对象。函数对象的构造函数为Function,可用它来定义函数,其基本语法格式如下。

var 变量 = new Function( "参数1" , "参数2" ,…, "函数体")

例如:

var sum3 = new Function("a" , "b" , "return a+b")

提示

function关键字定义了一个函数对象,这与Function构造函数一致。在语句定义方法中,函数名用于引用定义的函数对象。在表达式或使用Function构造函数定义函数时,赋值语句左侧的变量用于引用定义的函数对象。

3.2.2 调用函数

调用函数

函数调用的基本语法格式如下。

函数名(参数)

如果是在表达式中或使用Function构造函数定义的函数,则用变量名作为函数名。

使用function关键字在语句中定义函数时,函数的定义可以放在当前页面中的脚本的任意位置,即允许函数的调用出现在函数定义之前。在表达式中或使用Function构造函数定义函数时,只能在定义之后通过变量名来调用函数。

函数可以在脚本中调用,也可以作为HTML的事件处理程序或URL。

【例3-17】 在脚本中调用函数。源文件:03\test3-17.html。

…
<body>
<script>
    document.write('1 + 2 = ' + sum(1, 2))       //在函数sum的定义之前调用函数
    function sum(a, b) {
        return a + b
    }
    var sum2 = function (a, b) {
        return a + b
    }
    var sum3 = new Function("a", "b", "return a+b")
    document.write('<br>3 + 4 = '+ sum2(3, 4))  //调用表达式中定义的函数
    document.write('<br>5 + 6 = '+ sum3(6, 5))  //调用构造函数定义的函数
    document.write('<br>7 + 8 = '+ sum(7, 8))   //调用语句中定义的函数
</script>
</body>
</html>

浏览器中的运行结果如图3-17所示。

图3-17 在脚本中调用函数

【例3-18】 将函数作为HTML的事件处理程序。源文件:03\test3-18.html。

…
<body>
    <script>
    function test() {
        document.write("<br>调用了test()函数")
    }
    </script>
    <button onclick="test()">调用test()函数</button>
</body>
</html>

在浏览器中单击“调用test()函数”按钮时,会打开提示对话框,如图3-18所示。

图3-18 将函数作为HTML的事件处理程序

【例3-19】 将函数作为URL。源文件:03\test3-19.html。

…
<body>
    <script>
    function test() {
        alert("调用了test()函数")
    }
    </script>
    <a href="javascript:test()">调用test()函数</a>
</body>
</html>

在浏览器中单击“调用test()函数”链接时,会打开提示对话框,如图3-19所示。

图3-19 将函数作为URL

3.2.3 带参数的函数

函数在定义时指定的参数称为形式参数,简称形参。调用函数时指定的参数称为实际参数,简称实参。在调用函数时,实参的值按先后顺序、一一对应地传递给形参。

带参数的函数

JavaScript是弱类型的,形参不需要指定数据类型。JavaScript不会检查形参和实参的数据类型,也不会检查形参和实参的个数。

1. 关于函数的参数个数

函数的length属性返回形参的个数。在函数内部,arguments数组保存调用函数时传递的实参。

【例3-20】 使用arguments数组获取实际参数。源文件:03\test3-20.html。

…
<body>
    <script>
        function getMax(a, b) {
            var max = Number.MIN_VALUE
            var len = arguments.length    //获得实际参数个数
            if (len == 0) {
                document.write("<br>没有传递实际参数!")
                return
            }
            document.write("<br>实际参数:")
            for (var i = 0; i < len; i++) {
                document.write(arguments[i] +"&nbsp;&nbsp;")
                if (arguments[i] > max)
                    max = arguments[i]
            }
            document.write("最大值为:" + max)
        }
        document.write("函数getMax形参个数为:" + getMax.length)
        getMax()
        getMax(10, 5)
        getMax(10, 5, 20)
    </script>
</body>
</html>

在浏览器中的运行结果如图3-20所示。

图3-20 使用arguments数组获取实际参数

2. 数组作为参数

在使用表达式或变量作为实参时,形参接收实参的值,所以在函数中形参的值改变,不会影响到实参。在使用数组作为实参时,形参接收的是数组的内存地址,即形参和实参引用了同一个数组。这种情况下,改变形参数组元素的值,通过实参数组对应元素获得的是改变后的值。

【例3-21】 使用数组作为参数。源文件:03\test3-21.html。

…
<body>
    <script>
        function test(x,y) {
            x[0] = "abc"
            y = 100
            document.write("<p>函数内:<br>形参x = " + x)
            document.write("<br>形参y = " + y)
        }
        var a = [1, 2], b = 10
        document.write("调用函数前:<br>实参a = " + a)
        document.write("实参b = " + b)
        test(a, b)
        document.write("<p>调用函数后:<br>实参a = " + a)
        document.write("<br>实参b = " + b)
    </script>
</body>
</html>

在浏览器中的运行结果如图3-21所示。

图3-21 使用数组作为实际参数

3. 对象作为参数

对象也可作为函数参数(对象的详细内容将在后面的章节中进行介绍)。与数组类似,形参和实参引用的是同一个对象。如果在函数中修改了形参对象属性值,实参对象也会反应属性值的变化。

【例3-22】 使用对象作为参数。源文件:03\test322.html。

…
<body>
    <script>
        function test(args) {
            document.write("<p>函数内:<br>args.name = " + args.name)
            document.write("<br>args.age = " + args.age)
            args.name = 'Java'
            args.age=15
            document.write("<br>修改后:<br>args.name = " + args.name)
            document.write("<br>args.age = " + args.age)
        }
        var a = { name: 'JavaScript', age: 25 }
        document.write("调用函数前:<br>a.name = " + a.name)
        document.write("<br>a.age = " + a.age)
        test(a)
        document.write("<p>调用函数后:<br>a.name = " + a.name)
        document.write("<br>a.age = " + a.age)
    </script>
</body>
</html>

在浏览器中的运行结果如图3-22所示。

图3-22 使用对象作为实际参数

3.2.4 函数的嵌套

JavaScript允许在函数内部嵌套函数的定义。嵌套定义的函数只能在当前函数内部使用。

【例3-23】 使用嵌套定义函数,实现两个数组的加法运算(对应元素相加)。源文件:03\test3-23.html。

…
<body>
    <script>
        function addArray(a, b) {
            function getMax(x, y) { return x > y ? 0 : 1 }                //返回长度较大的数组的序号
            var alen = a.length
            var blen = b.length
            var index = getMax(alen, blen)
            var temp = new Array()                                        //创建一个空数组
            for (var i = 0, len = arguments[index].length; i < len; i++)  //将较长的数组复制到临时数组中
                temp[i] = arguments[index][i]
            for (var i = 0, len = arguments[1-index].length; i < len; i++)  //将较短的数组与临时数组做加法
                temp[i] += arguments[1 - index][i]                          //做加法
            return temp
        }
        var a = [1, 3, 5]
        var b = [2, 4, 6, 8, 10]
        var c = addArray(a, b)
        document.write('数组a = '+ a)
        document.write('<br>数组b = '+ b)
        document.write('<br>数组a + b = '+ c)
    </script>
</body>
</html>

在浏览器中的运行结果如图3-23所示。

图3-23 嵌套定义函数

3.2.5 递归函数

递归函数是指在函数的内部调用函数自身,形成递归调用。使用递归函数必须注意递归调用的结束条件。若递归调用无法停止,则会导致运行脚本的浏览器崩溃。

【例3-24】 使用递归函数计算阶乘。源文件:03\test3-24.html。

…
<body>
    <script>
        function fact(n) {
            if (n <= 1)
                return 1  //递归调用结束
            return n * fact(n - 1)
        }
        for (var i = 0; i <= 10; i++){
            document.write('<br>'+i + '! = '+ fact(i))
        }
    </script>
</body>
</html>

在浏览器中的运行结果如图3-24所示。

图3-24 使用递归函数计算正整数阶乘