zoukankan      html  css  js  c++  java
  • 【设计模式必备知识】函数柯里化

     说实话,函数柯里化我真的有点疑惑,一直没有想到合理的应用的场景,于是决定今天老子要吃掉这块肉 ,哼~  接下来,我们一起来了解一下函数柯里化吧

     函数柯里化的概念

      curring又称作为部分求值,一个curring的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另一个函数,

    刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。

    下面例子为,每天计算开销,月底进行结算, 这个只要用于保存参数,或者判断是否需要进行一次性求值.

    var cost = (function () {
      var args = [];
      return function () {
        if (arguments.length === 0) {
          var money = 0;
          for (var i = 0, l = args.length; i < l; i++) {
            money += args[i]
          }
          return money;
        }
        else { 
          Array.prototype.push.apply(args, arguments)
        }
      }
    })()
    cost(200)
    cost(300)
    cost()//500

    接下来我们编写一个通用的function curring(){},该函数接收一个参数,即将要被curring的函数。
    var curring = function (fn) {
      var arg = [];
      return function () {
        if (arguments.length === 0) {
          return arg
        }
        else {
          [].push.apply(arg, arguments);
          return arguments.callee // arguments.callee(代表当前正在执行的函数)
    } } }; 
    var cost = (function() {
      var money = 0
      return function() {
        for (var i = 0, l = arguments.length; i < l; i++) {
          money += arguments[i]
        }
        return money
      }
    })()
    var cost = curring(cost)
    cost(300)     
    

     uncurring的概念

    在javaScirpt中,当我们调用对象的某个方法时,其实不用去关心该对象原本是否被设计为拥有这个方法,这是动态类型的特点,也是常说的鸭子类型思想

    一个对象未必只能使用它自身的方法,我们可以使用 call和aplly借用其他不属于自己的方法。

    让类数组去借用Array.prototype的方法,是call和apply的常见的应用 ,

    这是call和apply的最常用的场景之一

    (function() {
        Array.prototype.push.call(arguments,4)
      console.log(arguments) } )(1,2,3)

    我们可以把泛化this的过程提取出来,那么uncurrying 

    Function.prototype.uncurrying = function () {
      console.log(this)//谁调用指向谁
      var self = this;
      return function () {
        var obj = Array.prototype.shift.call(arguments);//传入参数为对象
        return self.apply(obj, arguments)//传入参数为数组
      }
    };
    var push = Array.prototype.push.uncurrying();
    
    (function () {
      push(arguments, 4);
      console.log(arguments,'arguments');
    })(1, 2, 3)  

    常用的函数柯里化的场景

    柯里化常见的作用的是什么呢?常见的作用是:

    1. 参数复用
    2. 延迟运行
    3. 扁平化
    var curry = function (fn) {
      var args = [].slice.call(arguments, 1)
      console.log(args,arguments)
      return function () {
        var newArgs = args.concat([].slice.call(arguments))//这句话有什么存在的意义????
        console.log([].slice.call(arguments),"argssssss")
        console.log(newArgs,"newArgs")
        return fn.apply(this, newArgs)
      }
    };
    function add(a, b) {
      return a + b
    };
    
    var addCurry = curry(add, 1, 2);
    addCurry(); // 3
    

      

  • 相关阅读:
    20191324读书笔记10
    20191324读书笔记十一
    实验三:个人贡献
    20191324读书笔记12
    CBMVC For Titanium Alloy 发布!
    让 PowerDesigner 支持 SQLite!
    在类库中调用资源文件实现国际化!
    理解依赖注入及其好处!
    CBMVC Titanium Framework 介绍
    .Net插件框架的实现及分析(二)
  • 原文地址:https://www.cnblogs.com/Ewarm/p/11928939.html
Copyright © 2011-2022 走看看