【Vue源碼】函數柯里化


概念:只傳遞給函數一部分參數來調用它,讓它返回一個函數去處理剩下的參數;

先看一個簡單例子,add函數接受 2 個參數(或者多個),addX函數接受 1 個參數。換而言之,所謂"柯里化",就是把一個多參數的函數,轉化為單參數函數。將一個函數轉換為一個新的函數:

// 非柯里化
function add(x, y) {
    return x + y;
}

add(1, 2) === 3; // true

// 柯里化
function addX(y) {
    return function(x) {
        return x + y;
    };
}

addX(2)(1) == 3; // true

如何實現柯里化函數 curry

在下面的例子中我們對 add 進行了柯里化,從結果上可以看到當參數為 1 個時返回的是個函數,當參數為 2 個的時候返回函數,當參數為 3 個的時候返回函數執行結果

var _ = require("ramda");

var add = function(a, b, c) {
    return a, b, c;
};

var curry_add = _.curry(add);

console.log(curry_add(1)); // 輸出函數
console.log(curry_add(1)(2)); // 輸出函數
console.log(curry_add(1)(2)(3)); // 輸出結果

根據上述的小栗子,可以得到,柯里化后的函數如果接受到全部參數則返回函數執行結果,否則返回一個柯里化函數

很容易想到以下偽代碼

var curry = function(fn) {
    return function() {
        // 假設柯里化的函數叫 curry_fn
        // if "curry_fn接受到的參數數量等於fn接受參數的數量"
        // return "fn的執行結果"
        // else return "一個柯里化函數"
    };
};

上述偽代碼是不是很像遞歸?

  • 遞歸出口:curry_fn接受到的參數數量等於fn接受參數的數量
  • 重復邏輯:return "一個柯里化函數"

於是有了以下簡單實現柯里化的代碼

var curry = function(fn) {
    var limit = fn.length; // fn接受的參數個數
    var params = []; // 存儲遞歸過程的所有參數,用於遞歸出口計算值

    return function _curry(...args) {
        params = params.concat(args); // 收集遞歸參數
        if (limit <= params.length) {
            // 返回函數執行結果
            return fn.apply(null, params);
        } else {
            // 返回一個柯里化函數
            return _curry;
        }
    };
};

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM