柯里化函数

高阶函数

高阶函数,简单来说就是函数参数中还有函数。
一个函数接收另一个函数作为参数变量的这个函数就是高阶函数。
JS函数实际上是指向某一个变量,变量可以指向一个函数,函数参数一定是能够
接收变量的。同时,函数的参数能够接收变量,一个函数可以接收另一个函数作为变量。

例如下面这个例子:

function test (a, b, fn) {
  return fn(a) + fn(b);
}

function square (x) {
  return Math.pow(x, 2);
}

var result = test(2, 3, square);
console.log(result); // 13

ECMAScript也给我们定义了一些高阶函数。
例如:map() 数据处理函数、reduce() 归纳函数、filter() 过滤函数等。
高阶函数具有便于扩展,在函数执行完毕后进行回调。

柯里化

柯里化是函数式编程思想的一种。
是美国逻辑学家Haskell Brooks Curry提出并命名的。
柯里化可以把接受多个参数的函数转换成接受一个单一参数的函数,
并且可以接受余下的参数并返回结果。

柯里化函数的优点

  1. 功能内聚
  2. 降低耦合
  3. 降低代码重复性
  4. 提高代码的适应性

柯里化案例

function add (a, b, c, d) {
  return a + b + c + d;
}

function curry (fn, len) {
  var len = len || fn.length;

  var func = function (fn) {
    var _args = [].slice.call(arguments, 1);

    return function () {
      var newArgs = _args.concat([].slice.call(arguments));
      return fn.apply(this, newArgs);
    }
  }

  return function () {
    var argsLen = arguments.length;

    if (argsLen < len) {
      var formatedArr = [fn].concat([].slice.call(arguments));
      return curry(func.apply(this, formatedArr), len - argsLen);
    } else {
      return fn.apply(this, arguments);
    }
  }
}

var curryAdd = curry(add);
console.log(curryAdd(1)(2)(3)(4));
console.log(curryAdd(1, 2)(3)(4));
console.log(curryAdd(1, 2, 3)(4));
console.log(curryAdd(1, 2, 3, 4));

柯里化的实际应用

可以使用柯里化处理数据请求问,比如请求数据有一个参数是动态的,不固定的。
我们对数据请求方法进行柯里化,获取到固定的值后再传入。

function getWeather (opt, data, success_cb, error_cc) {
  $.ajax({
    url: opt.url,
    type: opt.type,
    dataType: opt.dataType,
    data: data,
    success: success_cb,
    error: error_cc
  })
}

var $get = curry(getWeather); // 柯里化处理

var $getWeatherById = $get({
  url: 'https://api.apiopen.top/musicRankingsDetails',
  type: 'POST',
  dataType: 'JSON'
})

$getWeatherById({
  type: 1
})
(function (data) {
  console.log(data);
})
(function (err) {
  console.log(err);
})