CoffeeScript 檢測(cè)與構(gòu)建丟失的函數(shù)

2022-06-29 17:06 更新

檢測(cè)與構(gòu)建丟失的函數(shù)

問題

你想要檢測(cè)一個(gè)函數(shù)是否存在,如果不存在則構(gòu)建該函數(shù)。(比如Internet Explorer 8的ECMAScript 5函數(shù))。

解決方案

使用存在賦值運(yùn)算符(?=)來把函數(shù)分配給類庫的原型(使用::簡寫),然后把它放于一個(gè)立即執(zhí)行函數(shù)表達(dá)式中(do ->)使其含有所有變量。

do -> Array::filter ?= (callback) ->
  element for element in this when callback element

array = [1..10]

array.filter (x) -> x > 5
# => [6,7,8,9,10]

討論

在JavaScript (同樣地,在 CoffeeScript)中,對(duì)象都有一個(gè)原型成員,它定義了什么成員函數(shù)能夠適用于基于該原型的所有對(duì)象。
在CoffeeScript中,你可以使用 :: 捷徑來訪問這個(gè)原型。所以如果你想要把過濾函數(shù)添加至數(shù)組類中,就執(zhí)行Array::filter=...語句。它能把過濾函數(shù)加至所有數(shù)組中。

但是,不要去覆蓋一個(gè)在第一時(shí)間還沒有構(gòu)造的原型。比如,如果Array::filter = ...已經(jīng)以快速本地形式存在于瀏覽器中,或者庫制造者擁有其對(duì)于Array::filter = ...的獨(dú)特版本,這樣以來,你要么換一個(gè)慢速的JavaScript版本,要么打破這種依賴于其自身Array::shuffle的庫。
你需要做的僅僅是在函數(shù)不存在的時(shí)候添加該函數(shù)。這就是存在賦值運(yùn)算符(?=)的意義。如果我們執(zhí)行Array::filter = ...語句,它會(huì)首先判斷Array::filter是否已經(jīng)存在。如果存在的話,它就會(huì)使用現(xiàn)在的版本。否則,它會(huì)添加你的版本。

最后,由于存在的賦值運(yùn)算符在編譯時(shí)會(huì)創(chuàng)建一些變量,我們會(huì)通過把它們封裝在立即調(diào)用函數(shù)表達(dá)式( IIFE )中來簡化代碼。這將隱藏那些內(nèi)部專用的變量,以防止泄露。所以假如我們寫的函數(shù)已經(jīng)存在,那么它將運(yùn)行,基本上什么都沒做然后退出,絕對(duì)不會(huì)對(duì)你的代碼造成影響。但是假如我們寫的函數(shù)并不存在,那么我們發(fā)送出去的僅是一個(gè)作為閉包的函數(shù)。所以只有你寫的函數(shù)能夠?qū)Υa產(chǎn)生影響。無論哪種方式,?=的內(nèi)部運(yùn)行都會(huì)被隱藏。

舉例

接下來,我們用上述的方法編譯了CoffeeScript并附加了說明:

// (function(){ ... })() 是一個(gè) IIFE, 使用 `do ->` 來編譯它。
(function() {

  // 它來自 `?=`  運(yùn)算符,用來檢查 Array.prototype.filter (`Array::filter`) 是否存在。
  // 如果確實(shí)存在,我們把它設(shè)置給其自身,并返回。如果不存在,則把它設(shè)置給函數(shù),并返回函數(shù)。
  // The IIFE is only used to hide _base and _ref from the outside world.
  var _base, _ref;
  return (_ref = (_base = Array.prototype).filter) != null ? _ref : _base.filter = function(callback) {

    // `element for element in this when callback element`
    var element, _i, _len, _results;
    _results = [];
    for (_i = 0, _len = this.length; _i < _len; _i++) {
      element = this[_i];
      if (callback(element)) {
        _results.push(element);
      }
    }
    return _results;

  };
// The end of the IIFE from `do ->`
})();
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)