@author: 郭瑞峰 @createTime: 2023/05/20 @updateTime: 2023/05/24
初窥门径
下面是一个题
// 定义一个函数resetAdd,让其所有值相加
const add = (a, b, c) => (a + b + c)
console.log(resetAdd(2, 4, 6)) // 12
console.log(resetAdd(2, 4)(6)) // 12
console.log(resetAdd(2)(4, 6)) // 12
console.log(resetAdd(2)(4)(6)) // 12
先想想看吧
想好了么?
咱再想想看
分析
共同:都是传三个参数 区别:传入顺序不一样
省略其他的,直接进入主题: 柯里化(curry)
柯里化(curry)
简单解释:函数传值传进去,传够了就运行,传不够就返回函数继续传,直到传够为止
详细解释:
在计算机科学中,柯里化(Currying)是把接受多个参数的
函数变换成接受一个单一参数(最初函数的第一个参数)的函
数,并且返回接受余下的参数且返回结果的新函数的技术。
这个技术由 Christopher Strachey 以逻辑学家Haskell
Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob
Frege 发明的。
柯里化函数实例
const curry = (fn) => {
const curried = (...args) => {
if (args.length >= fn.length) {
// 传参数量够,直接执行
return fn.apply(this, args)
} else {
// 传参数量不够,返回函数继续传递函数
return (...args2) => curried.apply(this, args.concat(args2))
}
}
return curried
}
柯里化就是这么简单,所以说方才的题写法就应该是这样
const add = (a, b, c) => (a + b + c)
const curry = (fn) => {
const curried = (...args) => {
if (args.length >= fn.length) {
return fn.apply(this, args)
} else {
return (...args2) => curried.apply(this, args.concat(args2))
}
}
return curried
}
const resetAdd = curry(add)
console.log(resetAdd(2, 4, 6)) // 12
console.log(resetAdd(2, 4)(6)) // 12
console.log(resetAdd(2)(4, 6)) // 12
console.log(resetAdd(2)(4)(6)) // 12
补充
函数的apply, call, bind
apply
Function.apply方法调用时,将this指针指向方法第一个参数,后续传参以数组形式传递,直接执行
const add = (a, b) => {
return a + b + this.c
}
const obj = { c: 3 }
// Function.apply(newThis, [...args])
console.log(add.apply(obj, [1, 2]))
// 6
call
Function.call方法调用时,将this指针指向方法第一个参数,后续传参直接传,直接执行
const add = (a, b) => {
return a + b + this.c
}
const obj = { c: 3 }
// Function.call(newThis, ...args)
console.log(add.call(obj, 1, 2))
// 6
bind
Function.bind方法调用时,将this指针指向方法第一个参数,后续传参直接传,返回函数
const add = (a, b) => {
return a + b + this.c
}
const obj = { c: 3 }
// Function.bind(newThis, ...args)
console.log(add.bind(obj, 1, 2))
// [Function: bound add]
console.log(add.bind(obj, 1, 2)())
// 6