• 手写柯里化


    科里化,就是将接受多个参数的函数变换成接受一个单一参数的函数。

    闭包的应用场景就是函数科里化。(延长变量的生命周期)

    参数复用,利用闭包将函数的参数储存起来,等参数达到一定数量时执行函数

    fn(x, y) -> fn(x)(y)

    上面的代码就是把fn函数做成嵌套函数,外层函数的返回值是内层函数。外层函数调用完之后,能接着调用。

    涉及到的概念,高阶函数,闭包,call/apply,argument。

    科里化执行函数的核心是:有参数传入时,收集参数,返回函数;收集参数完毕,执行,返回值。

    第一种方法:比较容易理解

    fn指的是源处理函数,如sum,currArgs 是调用curry时传入的参数列表,比如(1,2)(3)

    function curry(fn, currArgs){return function(){
            let args =  Array.from(arguments);
            // 首次调用的时候,若未提供最后一个参数currArgs,则不用进行args拼接
            if(currArgs !== undefined){
                args = args.concat(currArgs)
            }
            // 递归调用,判断args的个数,是否与fn的参数相对能,相等了就可以把参数都传给fn,进而输出;否则继续递归调用,一直到两者相等。
            if(args.length < fn.length){  // fn.length 是fn函数参数的个数
                return curry(fn, args);
            }
            return fn.apply(null, args);
        }
    }
    function sum(a, b, c) {
        console.log(a + b + c);
    }
    
    const fn = curry(sum);
    
    fn(1, 2, 3); // 6
    fn(1, 2)(3); // 6

      第二种方法,

    const curry = (fn) => {
        if (typeof fn !== 'function') {
            console.log('function')
          throw Error('No function provided')
        }
    
        return function curriedFn (...args) {
            // 括号里扩展运算符的作用,是把传过来的参数变成数组。
            // 等同于 args = Array.from(arguments);
    
          if (fn.length > args.length) {  // 未达到触发条件,继续收集参数
            return function () {
                /**
                 * [].slice.call(arguments) 将类数组转化为数组,
                 * 上一行代码的原理是call会将slice方法内部的this就会被替换成arguments,
                 * 并循环遍历arguments,复制到新数组返回,这样就得到了一个复制arguments类数组的数组对象。
                 * 等同 Array.from(arguments)
                 * 也等同于 Array.prototype.slice.call(arguments)
                 */
              return curriedFn.apply(null, args.concat(Array.from(arguments)))
            }
          }
        //   apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.
        // Function.apply(obj,args)方法能接收两个参数
        // obj:这个对象将代替Function类里this对象
        // args:这个是数组,它将作为参数传给Function(args-->arguments)       
          return fn.apply(null, args)
        //   args作为参数,被fn调用。
        }
      }
    
      const multiply = (x, y, z) => x*y*z;
      const curryMul = curry(multiply);
      const result = curryMul(1)(2)(3); // 1*2*3 = 6
      console.log('result',result)
  • 相关阅读:
    做项目时写的数据库操作类。SqlHelper.cs(三)
    写的登录三层结构demo(工厂模式)
    在GridView中进行排序
    微信小程序 POST请求
    mysql replace into用法详细说明
    ThinkPHP Where 条件中使用表达式
    Google发转码工具 可将安卓程序转至iOS
    IOS笔记 本地化多语言支持
    persits.jpeg 水印组件
    PHP 数组操作
  • 原文地址:https://www.cnblogs.com/jwenming/p/14494123.html
Copyright © 2020-2023  润新知