# 理解Javascript的柯里化

damonare

<!-- more -->

## 正文

• 纯函数
• 柯里化
• 高阶函数

### 什么是柯里化

``````function sum(a, b, c) {
return a + b + c;
}
// 调用
sum(1, 2, 3); // 6``````

``````function sum(a) {
return function (b) {
return function(c) {
return a + b + c;
}
}
}
// 调用
let sum1 = sum(1);
let sum2 = sum1(2);
sum2(3); // 6``````

``````sum1 = function(b) {
return function(c) {
// 注意此时变量a存在于闭包中，可以调用，a = 1
return a + b + c;
}
}``````

``````sum2 = function(c) {
// 变量a,b皆在闭包中, a = 1, b = 2
return a + b + c;
}``````

### 柯里化函数的作用

``````function volume(length, width, height) {
return length * width * height;
}
volume(200, 100, 200);
volume(200, 150, 100);
volume(200, 50, 80);
volume(100, 50, 60);``````

``````function volume(length, width, height) {
return function(width) {
return function(height) {
return length * width * height;
}
}
}
let len200 = volume(200);
len200(100)(200);
len200(150)(100);
len200(50)(80);
volume(100)(50)(60);``````

``````function execOnce(fun) {
let flag = true;
return function() {
if (flag) {
fun && fun();
flag = false;
}
}
}
let onceConsole = execOnce(function() {
console.log('只打印一次');
});
onceConsole();
onceConsole();``````

``````let onceConsole = function() {
if (flag) {
(function() {
console.log('只打印一次');
})()
flag = false;
}
}``````

### 通用柯里化函数的实现

`````` // 第一版
var curry = function (fn) {
var args = [].slice.call(arguments, 1);
return function() {
var newArgs = args.concat([].slice.call(arguments));
return fn.apply(null, newArgs);
};
};
return a + b;
}

//或者

``````var addFun = curry(function(a, b,c) {
return a + b + c;
}, 1);

``````function curry(fn, args) {
var length = fn.length;
args = args || [];
return function(...rest) {
var _args = [...args, ...rest];
return _args.length < length
? curry.call(this, fn, _args)
: fn.apply(this, _args);
}
}
var fn = curry(function(a, b, c) {
console.log(a + b + c);
});
fn('a', 'b', 'c'); // abc
fn('a', 'b')('c'); // abc
fn('a')('b')('c'); // abc``````

## 后记

• 回复「666」，可领取一揽子前端技术书籍；

2.5k 声望
424 粉丝