函数柯里化: 接收一部分参数,返回一个函数接收剩余参数,接收足够参数后,执行原函数。
虽然开发中没用到过,但是还是记录一下,或许面试官会问呢
function curry(fn) {
// 其上下文入口,可能是tag1, 也可能是tag2
// 拿到第一个参数fn以外的剩余参数,因为要保存这个参数
let preArgs = Array.prototype.slice.call(arguments, 1)
// 返回一个函数,fn调用的时候在global执行,而不在自身的词法作用域curry里执行,所以就形成了一个闭包
return function() {
// 拿到curry的arg和回调函数的ags做拼接
let newArgs = [...preArgs, ...arguments]
if(newArgs.length >= fn.length ) {
return fn.apply(this, newArgs)
} else {
// 参数不足够就保存之前的参数,等待足够后再执行函数
return curry.call(this, fn, ...newArgs) // tag2
}
}
}
fn = curry(function(a, b, c, d) {
return a+b+c+d
})
fn(1,2)(3)(4)
fn1 = curry(function(a, b, c, d) { // tag1
return a+b+c+d
}, 1,2,3)
fn1(4)
其实还有看到过toString方法,但是感觉不太好。一般情况下也不提倡修改对象本身的toString属性,其做隐式类型转换的时候可能会造成不好的影响。
toStirng换成__defineGetter__试试
// 实现一个不限参数的累加
// 原理和柯里化相似
function add() {
let preArgs = [...arguments]
function sum () {
let newArgs = [...preArgs, ...arguments]
return add.apply(this, newArgs)
}
sum.__defineGetter__('value', () => {
return preArgs.reduce((a,b) => a + b)
})
return sum
}
let x = add(1,2,3)(4,5)(6)(7)
// 与其隐式显示调用toString方法,不如显示调用获取值
console.log(x.value)