javascript中關於匿名函式高階介紹

螞蟻小編發表於2017-04-04

下面介紹一下比較常用的js中對於匿名函式的封裝,比如jQuery 封裝、Backbone 封裝、Underscore 封裝。建立一個自呼叫匿名函式,設計引數window,並傳入window物件。

而這個過程的目的則是:

使得自身的程式碼不會被其他程式碼汙染,同時也可以不汙染其他程式碼。

一.jQuery 封裝:

jQuery1.7.1裡面的封裝程式碼大致是下面這樣,當然隨著版本的提升或許會有所改變。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
(function( window, undefined ) {
  window.jQuery = window.$ = jQuery;
  if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
    define( "jquery", [], function () { return jQuery; } );
  }
})( window );

我們就可以在window中呼叫jQuery,如下兩種方式都是可以的:

[JavaScript] 純文字檢視 複製程式碼
window.$
window.jQuery

於是我們就可以建立一個類似的封裝:

[JavaScript] 純文字檢視 複製程式碼
(function(window, undefined) {
  var PH = function() {
  }
})(window)

相比於上面只是少了兩步

(1).定義jQuery的符號及全域性呼叫。

(2).非同步支援。

於是找了下更早期的jQuery的封裝,方法上大致是一樣的,除了如下:

[JavaScript] 純文字檢視 複製程式碼
if (typeof window.jQuery == "undefined") {
  var jQuery = function() {};
  if (typeof $ != "undefined")
    jQuery._$ = $;
  var $ = jQuery;
};

很神奇的判斷方法,以致於沒有辦法重寫上一步的jQuery。

只好看看最新的jQuery的封裝是怎樣的,發現除了加了很多功能以外,基本上思想還是不變的

[JavaScript] 純文字檢視 複製程式碼
(function(global, factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        module.exports = global.document ?
            factory(global, true) :
            function(w) {
                if (!w.document) {
                    throw new Error("jQuery requires a window with a document");
                }
                return factory(w);
        };
    } else {
        factory(global);
    }
}(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
    var jQuery = function() {
        console.log('jQuery');
    };
    if (typeof define === "function" && define.amd) {
        define("jquery", [], function() {
            return jQuery;
        });
    };
    strundefined = typeof undefined;
    if (typeof noGlobal === strundefined) {
        window.jQuery = window.$ = jQuery;
    };
    return jQuery;
}));

在使用瀏覽器的情況下

[JavaScript] 純文字檢視 複製程式碼
typeof module ="undefined"

所以上面的情況是針對於使用Node.js等的情況下判斷的,這也表明jQuery正在變得臃腫。

二.Backbone 封裝:

[JavaScript] 純文字檢視 複製程式碼
(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
            root.Backbone = factory(root, exports, _, $);
        });
    } else if (typeof exports !== 'undefined') {
        var _ = require('underscore');
        factory(root, exports, _);
    } else {
        root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
    }
}(this, function(root, Backbone, _, $) {
    Backbone.$ = $;
    return Backbone;
}));

除了非同步支援,也體現了其對於jQuery和underscore的依賴

[JavaScript] 純文字檢視 複製程式碼
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
            root.Backbone = factory(root, exports, _, $);
        });

表明backbone是原生支援requirejs的。

三.Underscore 封裝:

Underscore,發現這個庫又佔用了一個符號 _

[JavaScript] 純文字檢視 複製程式碼
(function() {
    var root = this;
    var _ = function(obj) {
        if (obj instanceof _) return obj;
        if (!(this instanceof _)) return new _(obj);
        this._wrapped = obj;
    };
    if (typeof exports !== 'undefined') {
        if (typeof module !== 'undefined' && module.exports) {
            exports = module.exports = _;
        }
        exports._ = _;
    } else {
        root._ = _;
    }
    if (typeof define === 'function' && define.amd) {
        define('underscore', [], function() {
            return _;
        });
    }
}.call(this));

總體上也和差不多都是匿名函式,除了最後用的是call()方法。

相關文章