柯里化?看这里就够了!

·  阅读 250

前言

你可能想了解柯里化,但概念听了一堆,什么时候用?

不知道,看完就忘。

本文会带你简单认识一下概念,更多的是实际应用。

什么是柯里化?

柯里化(curry)是函数式编程的一种概念,维基百科是这么说的:

currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each takes a single argument

柯里化是将接受多个参数的函数转换为只接受一个参数的函数序列的技术。

???? 一头雾水。带你们先看例子再理解什么是柯里化。

例子

Add 柯里化

最简单的例子:

// 无柯里化
function add (x, y) {return x + y}
// 柯里化
const add = x => y => x + y
add(1)(2) // 3

// 高级版
const curry = (fn, ...args) => args.length >= fn.length ? fn(...args) : (..._args) => curry(fn, ...args, ..._args)
const baseAdd = (x, y, z) => x + y + z
const add = curry(baseAdd)
console.log(add(1, 2, 3));  // 6
console.log(add(1)(2)(3));  // 6
console.log(add(1, 2)(3));  // 6
console.log(add(1)(2, 3));  // 6
复制代码

可行吗?可行。有用吗?面试有用。

如果你为了面试,看到这里就够了。如果你想实际应用,接着往下看。

类型判断 柯里化

// 无柯里化
function isArray(v) {
    return Object.prototype.toString.call(v).slice(8, -1) === "Array";
}

function isObject(v) {
    return Object.prototype.toString.call(v).slice(8, -1) === "Object";
}

function isString(v) {
    return Object.prototype.toString.call(v).slice(8, -1) === "String";
}
// 柯里化
function getType(type) {
  return function(v) {
    return Object.prototype.toString.call(v).slice(8, -1) === type;
  };
}

const isArray = getType("Array");
const isObject = getType("Object");
const isString = getType("String");
复制代码

我们先写一个 getType 函数,该函数的作用是传入什么类型,返回一个判断什么类型的函数。然后使用 isString = getType("String") 来实现 isString 函数。

肉眼可见的是,代码行数变少了、且随着函数的增多会少的更多;另一个优点是我们优化判断逻辑,可以只优化柯里化中的一句,而不需要更改 N 个判断函数。

结论

通过第一个例子,我们可以看到柯里化的作用,但我们不知道它为何这么用,而第二个例子可以明白柯里化的实际应用。

为什么很多例子完全脱离了实际呢?私以为有两种:一种是面向讲课编程,一种是面向面试编程。

我们再来看这句话:柯里化是将接受多个参数的函数转换为只接受一个参数的函数序列的技术。

理论上是这样的,但如果我们这么用:

function getBool(trueFlag , falseFlag) {
  return function(v) {
    if (v === trueFlag) return true
    else if (v === falseFlag) return false
    else return null
  } 
}

export const stringToBool = getBool('true', 'false')
export const oneOrZeroToBool = getBool(1, 0)
export const oneOrZeroStrToBool = getBool('1', '0')
复制代码

它实际上接收了两个参数,那它是不是柯里化呢?不是的话它是什么?

它在我的眼里就是柯里化,尽信书不如无书

分类:
前端