成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS專題之函數(shù)柯里化

wudengzan / 2732人閱讀

摘要:有這樣的說法,并非柯里化有什么意義,而是,當函數(shù)可以作為函數(shù)的參數(shù)和返回值,成為函數(shù)式編程語言后,就會不可避免地產(chǎn)生函數(shù)柯里化。函數(shù)柯里化允許和鼓勵你分隔復雜功能變成更小更容易分析的部分。那么用函數(shù)柯里化就能實現(xiàn)提前返回。

#### 前言
在計算機科學中,柯里化(英語:Currying),又譯為卡瑞化或加里化,是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結果的新函數(shù)的技術。

#### 一、為什么會有函數(shù)柯里化?
Currying 的重要意義在于可以把函數(shù)完全變成「接受一個參數(shù);返回一個值」的固定形式,這樣對于討論和優(yōu)化會更加方便。

將關注的重點聚焦到函數(shù)本身,而不因冗余的數(shù)據(jù)參數(shù)分散注意力。

有這樣的說法,并非柯里化有什么意義,而是,當函數(shù)可以作為函數(shù)的參數(shù)和返回值,成為函數(shù)式編程語言后,就會不可避免地產(chǎn)生函數(shù)柯里化。

#### 二、具體實現(xiàn)
先來一個簡單的 add 函數(shù)

function add(x, y) {
    return x + y;
}

add(2, 3);  // 5

重要的概念多說一遍:函數(shù)柯里化就是接收多個參數(shù)的函數(shù)變換為接收一個函數(shù),并返回接收余下參數(shù),最終能返回結果的技術
。

那么,繼續(xù):

function add(x) {
    return function(y) {
        return x + y;
    }
}

add(2)(3);  // 5

所以,曾經(jīng)的一個函數(shù),因為閉包操作(返回函數(shù)并訪問了自由變量的行為),變成了多個接收一個參數(shù)的函數(shù)。

所以簡單來講:函數(shù)柯里化就是意圖將函數(shù)的參數(shù)變成一個。讓函數(shù)可以輸入一個值,就返回一個相對應的值,從而實現(xiàn)純函數(shù)化。

為什么函數(shù)式編程要求函數(shù)必須是純的,不能有副作用?因為它是一種數(shù)學運算,原始目的就是求值,不做其他事情,否則就無法滿足函數(shù)運算法則了。在函數(shù)式編程中,函數(shù)就是一個管道(pipe)。這頭進去一個值,那頭就會出來一個新的值,沒有其他作用。

所以良好的編程規(guī)范是盡可能讓函數(shù)塊做一個事情,實現(xiàn)可復用性,可維護性。

上面的例子中,如果有很多個參數(shù)怎么辦,難道一層層嵌套?

我們繼續(xù):

function plus(value) {
    "use strict";
    var add = function () {
        var args = [];
        var adder = function adder() {
            Array.prototype.push.apply(args,Array.prototype.slice.apply(arguments))
            return adder;
        }
        adder.toString = function () {
            return args.reduce(function(a, b) {
                return a + b;
            })
        }
        return adder;
    }
    return add()(value);
}

plus(2)(3)(5).toString();  // 10;

上面的代碼看起來不那么優(yōu)雅,如果是減法,我們就得又重新為減法寫這么多的代碼。像 lodash, underscore 這些工具庫,都提供了柯里化的工具函數(shù)。

我們一起來試著實現(xiàn):

function curry(fn, args) {
    var length = fn.length;  // 函數(shù)參數(shù)的長度

    // 閉包保存參數(shù)列表
    args = args || [];

    return function() {
        // 獲取參數(shù)列表。
        var _args = args.slice(0);
        
            Array.prototype.push.apply(_args, Array.prototype.slice.call(arguments))

        if (_args.length < length) {
        // 如果傳入的參數(shù)列表長度還沒有超過函數(shù)定義時的參數(shù)長度,就 push 新的參數(shù)到參數(shù)列表中保存起來。
        
            // 自己調(diào)用自己,將保存的參數(shù)傳遞到下一個柯里化函數(shù)。
            return curry.call(this, fn, _args);
        }
        else {
        // 如果傳入的參數(shù)列表長度已經(jīng)超過函數(shù)定義時的參數(shù)長度,就執(zhí)行。
            return fn.apply(this, _args);
        }
    }
}
三、應用場景

函數(shù)柯里化的好處有幾個:

參數(shù)復用;

提前返回;

延遲計算/運行。

函數(shù)柯里化允許和鼓勵你分隔復雜功能變成更小更容易分析的部分。這些小的邏輯單元顯然是更容易理解和測試的,然后你的應用就會變成干凈而整潔的組合,由一些小單元組成的組合。

文章開篇的 add 函數(shù),假如,每次調(diào)用加法有一個初始值會怎樣?

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

var addTen = add(10);

var addSix = add(6);

addTen(2)(3);  // 15;

addSix(7)(8);  // 21;

以上代碼就實現(xiàn)了參數(shù)復用,保存固定參數(shù)的函數(shù)。

看一個經(jīng)典的例子:
元素綁定事件監(jiān)聽器:

var addEvent = function(el, type, fn, capture) {
    if (window.addEventListener) {
        el.addEventListener(type, function(e) {
            fn.call(el, e);
        }, capture);
    } else if (window.attachEvent) {
        el.attachEvent("on" + type, function(e) {
            fn.call(el, e);
        });
    } 
};

以上代碼是為了兼容 IE 瀏覽器對 DOM 事件綁定做的函數(shù)封裝。

問題在于,每次對 DOM 元素進行事件綁定時,函數(shù)內(nèi)部都會走一遍 if else。那么用函數(shù)柯里化就能實現(xiàn)提前返回。

var addEvent = (function(){
    if (window.addEventListener) {
        return function(el, sType, fn, capture) {
            el.addEventListener(sType, function(e) {
                fn.call(el, e);
            }, (capture));
        };
    } else if (window.attachEvent) {
        return function(el, sType, fn, capture) {
            el.attachEvent("on" + sType, function(e) {
                fn.call(el, e);
            });
        };
    }
})();
總結

函數(shù)柯里化是“函數(shù)是一等公民”的編程語言環(huán)境形成的編程風格,利用了函數(shù)能作為參數(shù)一級返回值以及利用了閉包保存變量的特點,是將多個參數(shù)的函數(shù)轉換為接收一個參數(shù),最后返回結果的技術。

歡迎關注我的個人公眾號“謝南波”,專注分享原創(chuàng)文章。

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/101449.html

相關文章

  • js 擴展 -- currying 柯里函數(shù)

    摘要:里也有柯里化的實現(xiàn),只是平時沒有在意。如果函數(shù)柯里化后雖然生搬硬套,不過現(xiàn)實業(yè)務也會有類似場景。 柯里化 先解釋下什么是 柯里化 在計算機科學中,柯里化(英語:Currying),又譯為卡瑞化或加里化,是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結果的新函數(shù)的技術。 js 里也有柯里化的實現(xiàn),只是平時沒有在意。先把原文簡介貼...

    Pocher 評論0 收藏0
  • JavaScript專題系列文章

    摘要:專題系列共計篇,主要研究日常開發(fā)中一些功能點的實現(xiàn),比如防抖節(jié)流去重類型判斷拷貝最值扁平柯里遞歸亂序排序等,特點是研究專題之函數(shù)組合專題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實現(xiàn)模式需求我們需要寫一個函數(shù),輸入,返回。 JavaScript 專題之從零實現(xiàn) jQuery 的 extend JavaScritp 專題系列第七篇,講解如何從零實現(xiàn)一個 jQuery 的 ext...

    Maxiye 評論0 收藏0
  • JavaScript專題函數(shù)柯里

    摘要:一個經(jīng)常會看到的函數(shù)的實現(xiàn)為第一版我們可以這樣使用或者或者已經(jīng)有柯里化的感覺了,但是還沒有達到要求,不過我們可以把這個函數(shù)用作輔助函數(shù),幫助我們寫真正的函數(shù)。 JavaScript 專題系列第十三篇,講解函數(shù)柯里化以及如何實現(xiàn)一個 curry 函數(shù) 定義 維基百科中對柯里化 (Currying) 的定義為: In mathematics and computer science, cu...

    zhangfaliang 評論0 收藏0
  • JavaScript專題函數(shù)

    摘要:專題系列第十四篇,講解偏函數(shù)以及如何實現(xiàn)一個函數(shù)定義維基百科中對偏函數(shù)的定義為翻譯成中文在計算機科學中,局部應用是指固定一個函數(shù)的一些參數(shù),然后產(chǎn)生另一個更小元的函數(shù)。 JavaScript 專題系列第十四篇,講解偏函數(shù)以及如何實現(xiàn)一個 partial 函數(shù) 定義 維基百科中對偏函數(shù) (Partial application) 的定義為: In computer science, pa...

    beita 評論0 收藏0
  • JavaScript專題函數(shù)組合

    摘要:專題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實現(xiàn)模式需求我們需要寫一個函數(shù),輸入,返回。這便是函數(shù)組合。 JavaScript 專題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實現(xiàn) pointfree 模式 需求 我們需要寫一個函數(shù),輸入 kevin,返回 HELLO, KEVIN。 嘗試 var toUpperCase = function(x) { return...

    周國輝 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<