JS函式呼叫(4種方法)
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 間接呼叫函式。