zoukankan      html  css  js  c++  java
  • 函数柯里化 curry

    一、函数柯里化的特性:

    (1)参数复用 $.ajax

    // 示例一
    function ajax(type,url,data) {
      var xhr = new XMLHttpRequest();
      xhr.open(type,url,true);
      xhr.send(data);
    }
    
    var ajaxCurry = curry(ajax);
    // 以GET请求为例
    GET('www.baidu.com','name=Derry');
    
    // 示例二
    function add(a,b,c){
      return a + b + c;
    }
    
    const curryAdd = function(a){
      return function(b){
        return function(c){
          return a + b + c;
        }
      }
    }
    
    console.log(add(5,10,15)); // 结果30
    
    const add5 = curryAdd(5); // 固定第一个参数。让表达式已经具有了一个参数5,向外暴露add5
    
    console.log(add5(10)(15)); // 30

    (2)提前返回 onclick... addEventListener()

    // 示例一
    var addEvent = function(el, type, fn, capture){
      if(window.addEventListener){
        el.addEventListener(type,function(e){
          fn.call(el,e);
        },capture);
      }else if(window.attachEvent){ // 兼容6.7.8
        el.attachEvent('on' + type,function(e){
          fn.call(el,e);
        })
      }
    }
    
    addEvent(a,'click',handleClick,true);
    addEvent(a,'click',handleClick,true);
    addEvent(a,'click',handleClick,true);
    
    // 示例二(优化版)
    var addEvent = (function(){
      if(window.addEventListener){
        return function(el, type, fn, capture){
          el.addEventListener(type,function(e){
            fn.call(el,e);
          },capture);
        }
      }else if(window.attachEvent){ // 兼容6.7.8
        return function(el, type, fn, capture){
          el.attachEvent('on' + type,function(e){
            fn.call(el,e);
          })
        }
      }
    })() // 自运行函数(闭包)

    (3)延迟执行 -> 不定参数

    // 使用柯里化可以将函数的参数积累起来到某个触发点时再进行参数的执行
    var totalScore = 0;
    // 柯里化
    var curryScore = function(fn){
      var _totalScore = [];
      return function(){
        if(arguments.length === 0){
          return fn.apply(null, _totalScore);
        }else{
          _totalScore = _totalScore.concat([].slice.call(arguments));
        }
      }
    }
    
    var curryAddScore = curryScore(function(){
      var i=0;len = arguments.length;
      for(i;i<len;i++){
        totalScore += arguments[i]
      }
    });
    
    curryAddScore(3);
    console.log(totalScore); // 0
    curryAddScore(2);
    console.log(totalScore); // 0
    curryAddScore(1);
    curryAddScore(1);
    console.log(totalScore); // 0
    curryAddScore(3);
    curryAddScore(); // 参数为0的时候,才触发业务逻辑代码
    console.log(totalScore); // 10

    二、总结

    // 柯里化封装
    function curry(fn,args){
      // 需要得到或者说判断 fn到底有几个参数 -- fn.length
      var length = fn.length; // length 起到了延迟执行的触发判断条件
      args = args || []; // args 参数复用
      return function(){
        var _args = args.slice(0), arg, i;
        for(i=0; i<arguments.length; i++){
          arg = arguments[i];
          _args.push(arg);
        }
        if(_args.length < length){
          return curry.call(this, fn, _args);
        }else{
          return fn.apply(this, _args);
        }
      }
    }
    
    function add(a,b,c){
      return a + b + c;
    }
    
    var curryAdd = curry(add);
    console.log(curryAdd(5)(10)(15)); // 30
    console.log(curryAdd(5,10)(15)); // 30
    console.log(curryAdd(5,10,15)); // 30
    var curryAdd5 = curryAdd(5);
    console.log(curryAdd5(10,15)); // 30
    

    .

  • 相关阅读:
    windows下Yarn安装与使用(两种方法)
    git配置公钥---解决码云出现git@gitee.com: Permission denied (publickey)
    npm使用国内镜像的两种方法
    【LeetCode】33. Search in Rotated Sorted Array (4 solutions)
    【LeetCode】83. Remove Duplicates from Sorted List
    【LeetCode】82. Remove Duplicates from Sorted List II
    【LeetCode】85. Maximal Rectangle
    【LeetCode】84. Largest Rectangle in Histogram
    【LeetCode】87. Scramble String
    【LeetCode】162. Find Peak Element (3 solutions)
  • 原文地址:https://www.cnblogs.com/crazycode2/p/9189936.html
Copyright © 2011-2022 走看看