1. currying 函数柯里化
1.1 什么是柯里化
将多个参数的函数,提取成接收更少参数的函数,即:提前接收部分参数,延迟执行,不立即输出结果,而是返回一个接收剩余参数的函数。
1.2 怎样实现
currying(add)(1)(2, 3)(4)(5)(6);
currying(add)(1)(2, 3)(4)(5)(6)( );
code
const currying = (fn, arr = []) => {
let originLength = fn.length;
return (...args) => {
arr = [ ...arr, ...args];
let currentLength = arr.length;
// 如果 原始函数需传入参数个数 > 返回的所有函数 参数总量
return originLength > currentLength ?
// 参数不够 继续递归 返回函数
currying(fn, arr) :
// 否则 返回函数调用 或者 回调函数 内包裹函数调用
// fn(...arr);
() => fn(...arr);
}
}
test
function add(a, b, c, d, e, f) {
let arr = Array.from(arguments),
sum = arr.reduce((sum, n) => sum + n, 0);
console.log(sum)
}
// 返回 函数调用方式
currying(add)(1)(2, 3)(4)(5)(6); // 21
// 返回 回调函数
currying(add)(1)(2, 3)(4)(5)(6)(); // 21
运用类型校验
批量产生 校验函数
const checkType = type => content => Object.prototype.toString.call(content) === `[object ${type}]`;
let types = [ "String", "Number", "Boolean", "undefined", "null", "function", "Object", "Array", "Symbol" ];
let utils = {};
types.forEach(type => utils[`is${type}`] = checkType(type));
utils.isString(""); // true
utils.isSymbol(Symbol()); // true
2. uncurrying 反柯里化
2.1 什么是反柯里化
将对象下的方法,提取出,可被其他对象使用。
2.2 怎样实现
toString("string");
方法(一)
// code
// const uncurrying = fn => (...args) => fn.call(...args);
const uncurring = fn => (context, ...args) => Reflect.apply(fn, context, args);
// or
const uncurring = fn => (context, ...args) => Function.prototype.apply.call(fn, context, args);
// test 1
let toString = uncurrying(Object.prototype.toString);
toString("string");
// "[object String]"
// test 2
let tom = {
name: "Tom",
introduce() {
console.log(`My name is ${this.name}.`);
}
}
let jerry = {
name: "Jerry",
}
uncurrying(tom.introduce)(jerry);
// My name is Jerry.
方法(二)
// code
// ES5
Function.prototype.uncurrying = function () {
let that = this;
return function () {
let arr = Array.prototype.slice.call(arguments);
return that.call(arr[0]);
}
}
// ES6
Reflect.defineProperty(Function.prototype, "uncurrying", {
value: function (fn) {
return (...args) => this.call(...args);
}
})
// test 1
let toString = Object.prototype.toString.uncurrying();
toString([]);
// "[object Array]"
// test 2
let tom = {
name: "Tom",
introduce() {
console.log(`My name is ${this.name}.`);
}
}
let jerry = {
name: "Jerry",
}
let introduce = tom.introduce.uncurrying();
introduce(jerry);
// My name is Jerry.