“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”
概念
将多参数的函数fn,转化成多个传入一个参数的函数,达到某个条件后执行函数fn
偏柯里化: 转化成多个传入一个或多个参数的函数
前言
Arguments对象
是一个对应于传递给函数的参数的类数组对象。--- MDN
是非箭头函数的局部变量,在函数内部使用
情景: 传递可变数量的参数的函数
区别: arguments.length --- 实参的个数 function.length --- 形参的个数
// 行为: 在非严格模式下,arguments会跟踪参数的值,
即修改参数a 的值,会改变arguments[0]的值;修改arguments[0]的值会改变a的值
但是使用了,解构赋值、剩余参数、默认参数会影响此行为
(function (a) {
a = 1;
console.log(arguments[0])
})(10)
(function (a) {
arguments[0] = 1
console.log(a)
})(9)
转化为数组,可使用数组的方法
Array.prototype.slice.apply(arguments)
[].slice.apply(arguments)
es5
Array.from(arguments)
[...arguments]
正文
原理: 利用了闭包将传入的参数存储起来
function curry1 (fn) {
const _argus = []
const length = fn.length // 条件
return (function inner(...argus){
if(args.length !== 0){
_argus.push(...argus)
}
const that = this
return args.length >= length ? fn.apply(that, _argus) : (...args)=>inner.apply(that,args)
//或 return args.length >= length ? fn.apply(that, _argus) : inner.bind(that)
})()
}
function curry2 (fn, ...agrs){
const that = this
return args.length >= fn.length ? fn.apply(that, args) : (...argus) => curry.call(that, fn, ...args,...argus)
}
// 不满足条件时,返回一个可传参的可调用的函数
使用场景
fn是多参数的,且参数类型没有很强的区分度
题目
(一)
// 单个单个参数传递
// calculate(1)(2)(3)('+')
function curring1 (fn, ...args) {
return function (x) {
const that = this
// 加号是判断条件
return x==='+' ? fn.apply(that, args) : curring1.call(that, fn, x, ...args)
}
}
const calculate1 = curring1(function(...args){
return args.reduce((acc, cur)=>acc+cur,0)
})
// 执行函数验证
console.log(calculate1(1)(2)('+')) //--- 3
(二)
// 分批参数传递
// calculate(1,2)(4)(3,'+')
function curring2 (fn) {
const that = this
return function inner(...args) {
const length = args.length;
if(length !== 0 && args[length-1] == '+'){
return fn.apply(that, args.slice(0, length-1))
}
return (...argus) => inner.call(that,...args, ...argus)
}
}
const calculate2 = curring2(function(...args){
return args.reduce((acc, cur)=>acc+cur,0)
})
// 执行函数验证
console.log(calculate2(1,2)(4)(3,'+')) // --- 10