柯里化
含义
- 在一个函数中首先填充几个参数(然后再返回一个新函数)的技术称为柯里化(Currying)
- 当一个函数有多个参数传递的时候,先传递一部分参数调用它(这部分参数以后永远不变)后返回一个新的函数接收剩余的参数,返回结果
Code
柯里化的简单例子
//es5
function checkAge (min) {
return function (age) {
return age >= min
}
}
// es6
const checkAge = min => ((age) => age >= min)
// 柯里化
checkAge16 = checkAge(12)
checkAge18 = checkAge(18)
// 执行
checkAge16(16)
// true
checkAge18(22)
// true
最常用的柯里化函数 bind()
// 手写实现
Function.prototype.myBind = function() {
var self = this
var args = Array.prototype.slice.call(arguments) // 将参数转为数组
var context = args[0] // 保存需要绑定的this上下文
// 返回一个新函数
return function() {
return self.apply(context, Array.prototype.concat.call(args, Array.prototype.slice.call(arguments)))
}
}
// 测试用例
function func(age, sex) {
const str = `${this.name}是一个 ${age}岁的 ${sex}同学`
console.log(str)
}
const student = {
name: '小明'
}
const newFunc = func.myBind(student, 18)
newFunc('男')
实现一个柯里化函数curry
function getSum (a, b, c) {
return a + b + c
}
// console.log(getSum.length)
const curried = curry(getSum)
console.log('curried(1, 2, 3)', curried(1, 2, 3))
console.log('curried(1)(2, 3)', curried(1)(2, 3))
console.log('curried(1)(2)(3)', curried(1)(2)(3))
function curry (func) {
return function curriedFn (...args) {
// 判断实参和形参的个数是否一致
if (args.length < func.length) {
// 不一致则继续返回一个新的函数,接收后面的传参
return function () {
return curriedFn(...args.concat(Array.from(arguments)))
}
} else if (args.length === func.length) {
// 一致,则调用func
return func(...args)
}
}
}
// 面试题
// plus(1)(1)(2)(3)(5).toString() === 12
function plus (n) {
let sum = n
let add = function (n) {
sum += n
return add
}
add.toString = function () {
return sum
}
return add
}
const res = plus(1)(1)(2)(3)(5).toString()
console.log(res === 12)
总结
- 柯里化可以让我们给一个函数传递较少的参数,得到一个已经记忆了某些固定参数的新函数
- 这是一种对函数参数的缓存
- 让函数变得更加灵活,让函数的粒度更小
- 可以把多元函数转换为一元函数,可以组合使用函数产生强大的函数
好好学习不会差,我是你们的航少,大家一起进步