# 柯里化1

**柯里化**, 即 **Currying** 的音译。

**Currying** 为实现多参函数提供了一个递归降解的实现思路——**把接受多个参数的函数变换成接受一个单一参数（最初函数的第一个参数）的函数，并且返回接受余下的参数而且返回结果的新函数。**

下面尝试对最简单的加法函数进行柯里化改造

```javascript
function add (x, y) {
  return (x + y)
}
```

## **第一层**

```javascript
function curriedAdd (x) {
  return function(y) {
    return x + y
  }
}
```

当然以上实现是有一些问题的：它并不通用，并且我们并不想通过重新编码函数本身的方式来实现 **Currying** 化。

## 第二层

```javascript
function currying (fn, ...args1) {
    return function (...args2) {
        return fn(...args1, ...args2)
    }
}

var increment = currying(add, 1)
```

在此实现中，`currying` 函数的返回值其实是一个接收剩余参数并且立即返回计算值的函数。**即它的返回值并没有自动被 Currying化 。所以我们可以通过递归来将 currying 的返回的函数也自动 Currying** 化。

## 第三层

```javascript
function trueCurrying(fn, ...args) {
    if (args.length >= fn.length) {
        return fn(...args)
    }
    return function (...args2) {
        return trueCurrying(fn, ...args, ...args2)
    }
}
```

以上的思想为

> **比较多次接受的参数总数与函数定义时的入参数量，当接受参数的数量大于或等于被 Currying 函数的传入参数数量时，就返回计算结果，否则返回一个继续接受参数的函数。**

```javascript
const curriedAdd = trueCurring(add)
curriedAdd(1,2) // 3
curriedAdd(1)(2) // 3
```

## 柯里化优势

1. 多参函数复用性
2. 函数式编程而生

## 柯里化劣势

1. 一些特性有其他解决方案

   如果我们只是想提前绑定参数，那么我们有很多好几个现成的选择，bind，箭头函数等，而且性能比Curring更好。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mm.ricky.moe/javascript/js-concept/ke-li-hua.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
