JavaScript 專題之惰性函數

JavaScript 專題系列第十五篇,講解惰性函數git

需求

咱們如今須要寫一個 foo 函數,這個函數返回首次調用時的 Date 對象,注意是首次。github

解決一:普通方法

var t;
function foo() {
    if (t) return t;
    t = new Date()
    return t;
}複製代碼

問題有兩個,一是污染了全局變量,二是每次調用 foo 的時候都須要進行一次判斷。瀏覽器

解決二:閉包

咱們很容易想到用閉包避免污染全局變量。閉包

var foo = (function() {
    var t;
    return function() {
        if (t) return t;
        t = new Date();
        return t;
    }
})();複製代碼

然而仍是沒有解決調用時都必須進行一次判斷的問題。函數

解決三:函數對象

函數也是一種對象,利用這個特性,咱們也能夠解決這個問題。ui

function foo() {
    if (foo.t) return foo.t;
    foo.t = new Date();
    return foo.t;
}複製代碼

依舊沒有解決調用時都必須進行一次判斷的問題。spa

解決四:惰性函數

不錯,惰性函數就是解決每次都要進行判斷的這個問題,解決原理很簡單,重寫函數。code

var foo = function() {
    var t = new Date();
    foo = function() {
        return t;
    };
    return foo();
};複製代碼

更多應用

DOM 事件添加中,爲了兼容現代瀏覽器和 IE 瀏覽器,咱們須要對瀏覽器環境進行一次判斷:對象

// 簡化寫法
function addEvent (type, el, fn) {
    if (window.addEventListener) {
        el.addEventListener(type, fn, false);
    }
    else if(window.attachEvent){
        el.attachEvent('on' + type, fn);
    }
}複製代碼

問題在於咱們每當使用一次 addEvent 時都會進行一次判斷。排序

利用惰性函數,咱們能夠這樣作:

function addEvent (type, el, fn) {
    if (window.addEventListener) {
        addEvent = function (type, el, fn) {
            el.addEventListener(type, fn, false);
        }
    }
    else if(window.attachEvent){
        addEvent = function (type, el, fn) {
            el.attachEvent('on' + type, fn);
        }
    }
}複製代碼

固然咱們也能夠使用閉包的形式:

var addEvent = (function(){
    if (window.addEventListener) {
        return function (type, el, fn) {
            el.addEventListener(type, fn, false);
        }
    }
    else if(window.attachEvent){
        return function (type, el, fn) {
            el.attachEvent('on' + type, fn);
        }
    }
})();複製代碼

當咱們每次都須要進行條件判斷,其實只須要判斷一次,接下來的使用方式都不會發生改變的時候,想一想是否能夠考慮使用惰性函數。

重要參考

Lazy Function Definition Pattern

專題系列

JavaScript專題系列目錄地址:github.com/mqyqingfeng…

JavaScript專題系列預計寫二十篇左右,主要研究平常開發中一些功能點的實現,好比防抖、節流、去重、類型判斷、拷貝、最值、扁平、柯里、遞歸、亂序、排序等,特色是研(chao)究(xi) underscore 和 jQuery 的實現方式。

若是有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。若是喜歡或者有所啓發,歡迎 star,對做者也是一種鼓勵。

相關文章
相關標籤/搜索