JavaScript 提供了 4 種函數調用:一般形式的函數調用、作為對象的方法調用、使用 call 和 apply 動態調用、使用 new 間接調用。
一般形式的函數調用
在默認狀態下,函數是不會被執行的。使用小括號()
可以激活並執行函數。在小括號中可以包含零個或多個參數,參數之間通過逗號進行分隔。
示例1
在下面示例中,使用小括號調用函數,然后直接把返回值傳入函數,進行第二次運算,這樣可以節省兩個臨時變量。
- function f(x,y) { //定義函數
- return x * y; //返回值
- }
- console.log(f(f(5,6), f(7,8))); //返回1680。重復調用函數
示例2
如果函數返回值為一個函數,則在函數調用時可以使用多個小括號反復調用。
- function f(x,y) { //定義函數
- return function () { //返回函數類型的數據
- return x * y;
- }
- }
- console.log(f(7,8) ()); //返回56,反復調用函數
示例3
設計遞歸調用函數,即在函數內調用自身,這樣可以反復調用,但最終返回的都是函數自身。
- function f() { //定義函數
- return f; //返回函數自身
- }
- console.log(f() () () () () () () () () () () ()); //返回函數自身
當然,上述設計方法在實際開發中沒有任何應用價值,不建議使用。
作為對象的方法調用
當一個函數被設置為對象的屬性值時,稱之為方法。使用點語法可以調用一個方法。
示例
下面示例創建一個 obj 對象,它有一個 value 屬性和一個 increment 屬性。increment 方法接收一個可選參數,如果該參數不是數字,那么默認使用數字 1。
- var obj = {
- value : 0,
- increment : function (inc) {
- this.value += typeof inc === 'number' ? inc :1;
- }
- }
- obj.increment();
- console.log(obj.value); //1
- obj.increment(2);
- console.log(obj.value); //2
使用點語法可以調用對象 obj 的方法 increment,然后通過 increment 方法改寫 value 屬性的值。在 increment 方法中可以使用 this 訪問 obj 對象,然后使用 obj.value 方式讀寫 value 屬性值。
使用 call 和 apply 動態調用
call 和 apply 是 Function 的原型方法,它們能夠將特定函數當做一個方法綁定到指定對象上,並進行調用。具體用法如下:
function.call(thisobj, args...)
function.apply(thisobj, [args])
function 表示要調用的函數;參數 thisobj 表示綁定對象,即 this 指代的對象;參數 args 表示要傳遞給被調用函數的參數。call 方法可以接收多個參數列表,而 apply 只能接收一個數組或者偽類數組,數組元素將作為參數列表傳遞給被調用的函數。
示例1
下面示例使用 call 動態調用函數 f,並傳入參數值 3 和 4,返回運算值。
- function f(x,y) { //定義求和函數
- return x + y;
- }
- console.log(f.call (null, 3, 4)); //返回7
在上面示例中,f 是一個簡單的求和函數,通過 call 方法把函數 f 綁定到空對象 null 身上,以實現動態調用函數 f,同時把參數 3 和 4 傳遞給函數 f,返回值為 7。實際上,f.call(null,3,4) 等價於 null.m(3,4)。
示例2
上面示例使用 call 調用,實際上也可以使用 apply 方法來調用函數 f。
- function f(x,y) { //定義求和函數
- return x + y;
- }
- console.log(f.apply(null, [3,4])); //返回7
如果把一個數組或偽類數組的所有元素作為參數進行傳遞,使用 apply 方法就非常便利。
示例3
下面使用 apply 方法設計一個求最大值得函數。
- function max() { //求最大值函數
- var m = Number.NEGATIVE_INFINITY; //聲明一個負無窮大的數值
- for (var i = 0; i < arguments.length; i ++) { //遍歷所有實參
- if (arguments[i] > m) //如果實參值大於變量m
- m = arguments[i]; //則把該實參值賦值給m
- }
- return m; //返回最大值
- }
- var a = [23,45,2,46,62,45,56,63]; //聲明並初始化數組
- var m = max.apply(Object, a); //動態調用max,綁定為Object的方法
- console.log(m); //返回63
在上面示例中,設計定義一個函數 max(),用來計算所有參數中的最大值參數。首先通過 apply 方法動態調用 max() 函數,然后把它綁定為 Object 對象的一個方法,並把包含多個值的數組傳遞給它,最后返回經過 max() 計算后的最大數組元素。
如果使用 call 方法,就需要把數組所有元素全部讀取出來,再逐一傳遞給 call 方法,顯然這種做法不是很方便。
示例4
也可以動態調用 Math 的 max() 方法來計算數組的最大值元素。
- var a = [23,45,2,46,62,45,56,63]; //定義並初始化數組
- var m = Math.max.apply(Object, a); //調用系統函數max
- console.log(m); //返回63
示例5
使用 call 和 apply 方法可以把一個函數轉換為指定對象的方法,並在這個對象上調用該方法。當函數動態調用之后,這個對象的臨時方法也就不存在了。
- function f() {
- return "函數f";
- }
- var obj = {};
- f.call(obj); //把函數f綁定為obj對象的方法
- console.log(obj.f()); //再次調用該方法,則返回編譯錯誤
call 和 apply 方法的主要功能如下:
- 調用函數。
- 修改函數體內的 this 指代對象。
- 為對象綁定方法。
- 跨越限制調用不同類型的方法。
本小節主要介紹了如何使用 call 和 apply 方法調用函數,由於涉及類型、對象和 this 知識,后續我們還會繼續深入講解。
new 命令間接調用
使用 new 命令可以實例化對象,這是它的主要功能,但是在創建對象的過程中會激活並運行函數。因此,使用 new 命令可以間接調用函數。
示例
下面示例簡單演示了如何用 new 命令,把傳入的參數值顯示在控制台。
- function (x,y) { //定義函數
- console.log("x =" + x + ", y =" + y);
- }
- new f(3,4);
使用 new 命令調用函數時,返回的是對象,而不是 return 的返回值。如果不需要返回值,或者 return 的返回值是對象,則可以選用 new 間接調用函數。