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
    

    .

  • 相关阅读:
    Mybatis 学习过程中出现空指针异常的错误【已解决】
    IntelliJ IDEA的常用设置及快捷键
    The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone错误的解决办法【已解决】
    IntelliJ IDEA安装教程及使用方法
    OA项目笔记
    Linux常用命令大全(四)
    Linux常用命令大全(三)
    Linux常用命令大全(二)
    Linux常用命令大全(一)
    Apache配置默认首页
  • 原文地址:https://www.cnblogs.com/crazycode2/p/9189936.html
Copyright © 2011-2022 走看看