美文网首页
函数柯里化(又称部分求值)

函数柯里化(又称部分求值)

作者: 付出的前端路 | 来源:发表于2018-03-21 10:37 被阅读0次

    柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

    简单理解:参数部分使用。外部函数处理部分应用,剩下的由外部函数的返回函数处理。

    柯里化有3个作用:1. 参数复用;2. 提前返回;3. 延迟计算/运行(实际项目中用的很少,但是ES5中的bind方法的本质就是用的函数柯里化,不考虑执行时的新增参数)。

    这里只讲参数复用和提前返回的两个常见用法:

    1.参数复用:

    // 一般函数写法
      function sum (x, y) {
         return x + y
      }
      console.log('普通函数求和', sum(10, 20))
      // 函数柯里化写法
      function sum_curry (x) {
        return function (y) {
          return x + y
        }
      }
    // 设置默认第一参数
     var addTen = sum_curry (10) // 30
    // 设置其它部分参数
     console.log('函数柯里化', addTen(40)) // 50
    

    2.提前返回
    “提前返回”,很常见的一个例子,兼容现代浏览器以及IE浏览器的事件添加方法
    一般写法

    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);
            });
        } 
    };
    

    上面的方法有什么问题呢?很显然,我们每次使用addEvent为元素添加事件的时候,(eg. IE6/IE7)都会走一遍if...else if ...,其实只要一次判定就可以了,怎么做?–柯里化。改为下面这样子的代码:

    函数柯里化写法

    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);
                });
            };
        }
    })();
    

    总结:
    张鑫旭

    最近在看《JavaScript模式》一书,天哪,里面出现的各种设计模式(如工厂模式、外观模式、观察者模式),一双手都数不过来。而且这些名词又很抽象,书一合,马上大眼瞪小眼了。这种感觉就像是,房间里来了10个黑人,每个黑人都有一个“¥%#…¥”的名字,好不容易勉强记住了,灯一关房间一黑,等再开灯的时候,每个黑人的名字都变成…..”hello”了 image

    其实这些模式在实际使用的时候,或多或少都使用过,当看到“模式”概念的时候,我们就会猛然惊起:“哦,原来这个就叫做‘观察者模式’等”。现在要讨论的问题是,我们有没有必要把这些“模式”都记住呢,都理解其对应的核心呢?这个问题类似于,我可以看懂NBA的篮球比赛,那我有没有必要把各个球队以及球队的队员都记住呢?

    如果想成为JS大神,从这个目标来看,这是需要的;好比优秀的篮球解说员必须要知道每个球队的名字、球员甚至周边八卦。但是,现实很重要。如果连JS函数相关的基本东西都驾驭不好,显然,硬是啃这些似懂非懂的概念只会造成混乱。如果你觉得可以更近一步,先通透几个自己习惯的熟悉的使用模式,足够应付实际项目;其他一些概念什么的,更多的只是噱头,实用性其实并不大。正如本文的柯里化,看上去很高级,似乎也有点用处,然而JS的灵活性使得很多实现完全摆脱“柯里化”这个概念的束缚,以更通俗易懂的方式实现。

    然而,即使实用性不高,我们还是要有所了解,因为,你不知道什么时候会用到它。比方说CSS中的display:table;某些情况下可以解决一些棘手问题(secret!

    image

    ).

    因此,本文的柯里化至少要知道个大概,如果你囫囵吞枣式的看到此处,只记得“柯里化==柯南”,你可以再稍微静点心重新看一下。我的笔头要比嘴巴犀利的多,因为,文字我可以静心琢磨:“如何讲述才能提起兴趣,才能让新手也能知其意会其形?” ,久而久之,就形成了这种菊紧的风格——更适合新手阅读,同时被“高人”不屑:“写得太罗嗦啦,直接一句话不就完事啦!”还时不时来一句“鉴定完毕”,恩,挺适合去验尸!

    参考文章
    张鑫旭

    相关文章

      网友评论

          本文标题:函数柯里化(又称部分求值)

          本文链接:https://www.haomeiwen.com/subject/cgknzxtx.html