1. 程式人生 > >簡析JavaScript中的Function型別(三)——作為值的函式

簡析JavaScript中的Function型別(三)——作為值的函式

開發十年,就只剩下這套架構體系了! >>>   

因為在ECMAScript中,函式名本身就是變數,所以函式也可以作為值來使用。也就是說,不僅可以像傳遞引數一樣把一個函式傳遞給另一個函式,而且可以將一個函式作為另一個函式的結果返回。

1. 作為引數

來看一個示例:

function callFn(fn, param){
  return fn(param);
}

function add5(num){
  return num + 5;
}

var value = callFn(add5, 10);
console.log(value);//15

首先聲明瞭一個callFn函式,它接收兩個引數,一個是要呼叫的函式,另一個是傳遞給要呼叫函式的引數。接下來建立了add5函式,然後使用callFn呼叫了add5,返回了add5的結果。

其實這裡使用匿名函式作為引數也是可以的,還是這個例子:

var value = callFn(function(num){
  return num + 5;
}, 10);
console.log(value);//15

看到這是不是覺得有點熟悉呢?其實類似的,我們一直在用:

setTimeout(function(){
  console.log('hello world');
}, 1000);

上面這段程式碼我想讀者一定不陌生吧,這是一個延遲函式,1秒鐘後執行第一個引數——匿名函式。setTimeout

是一個定義在window上的全域性函式,第一個引數是要執行的回撥函式,第二個引數是延遲的毫秒數。

再來看另一個例子:

$('#id').click(function(){
  console.log('點選了');
});

這是jQuery中的寫法,$()是一個函式呼叫,這個函式接收的引數是'#id',返回了一個jQuery物件,在這個物件上再呼叫click()方法,這個方法接收一個匿名函式作為引數,這樣就完成了click事件的繫結。

下面是jQuery 3.3.1版本131~144行的程式碼,我們看到jQuery就是一個函式。

var
  version = "3.3.1",

  // Define a local copy of jQuery
  jQuery = function( selector, context ) {

    // The jQuery object is actually just the init constructor 'enhanced'
    // Need init if jQuery is called (just allow error to be thrown if not included)
    return new jQuery.fn.init( selector, context );
  },

  // Support: Android <=4.0 only
  // Make sure we trim BOM and NBSP
  rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;

這是第10333~10358行:

var
  // Map over jQuery in case of overwrite
  _jQuery = window.jQuery,

  // Map over the $ in case of overwrite
  _$ = window.$;

  jQuery.noConflict = function( deep ) {
    if ( window.$ === jQuery ) {
      window.$ = _$;
    }

    if ( deep && window.jQuery === jQuery ) {
      window.jQuery = _jQuery;
    }
    return jQuery;
  };
  // Expose jQuery and $ identifiers, even in AMD
  // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
  // and CommonJS for browser emulators (#13566)
  if ( !noGlobal ) {
    window.jQuery = window.$ = jQuery;
  }

對於其中的邏輯我們大可不必理會,從中可以看出,這段程式碼大致做了這樣一件事:

window.jQuery = window.$ = jQuery;

這樣就能理解,為什麼我們可以使用$()了,$()jQuery()是等同的。

2. 作為返回值

先來看一段程式碼:

var arr = [8, 1, 35, 3, 10];

//升序
function ascSort(v1, v2) {
  return v1 - v2;
}
arr.sort(ascSort);
console.log(arr);//[1, 3, 8, 10, 35]

//降序
function descSort(v1, v2){
  return v2 - v1;
}
arr.sort(descSort);
console.log(arr);//[35, 10, 8, 3, 1]

這是JavaScript陣列(一)——排序中講的給陣列排序的程式碼,我們看到升序和降序分別聲明瞭一個函式,現在我們想能不能把這兩個函式合併為一個呢?來看下面的程式碼:

var arr = [8, 1, 35, 3, 10];

function comparisonFn(flag){
  if(flag){
    // true 升序
    return function(v1, v2){
      return v1 - v2;
    }
  }else{
    // false 降序
    return function(v1, v2){
      return v2 - v1;
    }
  }
}

arr.sort(comparisonFn(false));
console.log(arr);//[35, 10, 8, 3, 1]

如程式碼所示,我們建立了一個函式,把真正的比較函式作為這個函式的返回值,在使用的時候通過給comparisonFn()傳遞true/false來控制升降序,達到了簡化程式碼的目的。

關於函式作為引數和返回值的例子還有很多,這裡就不一一列舉了,相信讀者隨著對JavaScript學習的不斷深入,以後還