到底JS柯里化在項目中怎麼用?

前言

[適合讀者]:有必定開發經驗的前端人員javascript

以前在不少文章裏面看了柯里化的相關知識,大多舉的例子都是實現累加累乘這些的函數,而後具體項目裏面怎麼用,實際場景不多提到,總感受看完以後好像理解了,又好像沒理解,可能主要仍是沒有一個實際的真實運用場景緻使咱們理解起來很困難,接下來我嘗試寫一些柯里化在項目中的運用但願能幫助你們理解這個東西html

柯里化

下面先說說柯里化的幾個特色,而後根據這幾個特色分別舉例來講明一下實際運用場景前端

  1. 提早返回
  2. 延遲執行
  3. 參數複用

提早返回

案例一(常見的兼容性判斷代碼)
  1. 封裝一個addEvent兼容低版本IE的代碼

這個是一個提早返回的經典案例,經過一個自執行函數來將if...else...判斷只執行一次,並返回了一個新的函數,那麼後續再次調用的時候就不會執行if...else...的判斷了,提高了代碼性能。java

var addEvent = (function() {
        if (window.addEventListener) {
          return function(el, type, cb, bubbing) {
            el.addEventListener(
              type,
              function(e) {
                cb.call(el, e);
              },
              bubbing
            );
          };
        } else if (window.attachEvent) {
          return function(el, type, cb, bubbing) {
            el.attachEvent('on' + type, function() {
              cb.call(el, e);
            });
          };
        }
      })();

複製代碼
  1. 封裝一個簡單的createXmlHttpRequest 方法

這個的原理同上app

var createXmlHttpRequest = (function() {
        var xmlHttp;
        if (window.XMLHttpRequest) {
          return function() {
            return new XMLHttpRequest();
          };
        } else if (window.ActiveXObject) {
          return function() {
            return new ActiveXObject('Msxml2.XMLHTTP');
          };
        }
      })();
複製代碼

經過上述兩個案例,咱們能夠發現提早執行大多數場景應該是用在咱們須要對不一樣終端作兼容處理的場景上面,那麼總結下要觸發提早執行這個場景,須要知足以下兩個條件:wordpress

  1. 函數中須要使用if...else...或者其餘的分支判斷
  2. 返回結果是一個新的函數,而不是一個具體的值

注: 使用柯里化返回結果是一個值而不是函數的話我的以爲不太須要使用函數

延遲執行

案例一 (節流防抖函數)
  1. 封裝一個防抖函數,節流函數也是一樣的延遲執行的道理
function debuonce(fn, time) {
        let timer;
        return function() {
          const _args = [].slice.call(arguments);
          clearTimeout(timer);
          timer = setTimeout(() => {
            fn.apply(this, _args);
          }, time);
        };
      }
複製代碼
案例二(bind函數)
  1. 封裝一個bind函數 bind方法的做用是對象冒充,改變函數的做用域,可是和call和apply的區別就是其返回值是一個函數,而且調用後並不執行這個函數,下面是一個bind函數的簡單示例,未考慮new的狀況。

詳細的bind函數能夠參照這篇文章:www.cnblogs.com/moqiutao/p/…性能

Function.prototype.bind = function(fn) {
        const args = [].slice.call(arguments, 1);
        const context = this;
        return function() {
          const _args = args.concat([].slice.call(arguments, 1));
          return context.apply(fn, _args);
        };
      };
複製代碼

經過上述案例能夠看出,通常觸發延遲執行場景,須要如下兩個條件:ui

  1. 返回一個新函數
  2. 新函數裏面有上面引用了外層函數做用域中的變量

參數複用

這個狀況能夠參考網上的累加累乘這些案例this

總結

函數柯里化確實比較難懂,初學者須要大量實踐纔可以明白其中的原委,雖然柯里化會有必定的性能問題,不過大多數人的代碼裏面性能問題基本上不會是由於使用了柯里化致使的,因此能夠放心使用。

本篇先寫這些案例,後續會繼續補充相關案例~

若是讀者還有一些實際案例,歡迎留言,我會對文章進行修改補充~

參考文章

JS中的柯里化(currying):www.zhangxinxu.com/wordpress/2…

學會函數柯里化(curry):www.codercto.com/a/54607.htm…

相關文章
相關標籤/搜索