何时函数的实际.length属性无法满足_.curry()的需求?
关于_.curry需要手动指定arity的实际场景示例
我完全明白你遇到的这个坑!当初我第一次用_.curry处理带默认参数或剩余参数的函数时也踩过同样的雷。下面给你几个非常常见的实际场景,能直观展示为什么必须手动指定arity:
场景1:使用剩余参数的函数
当函数用剩余参数...接收参数时,func.length会变成0——因为JS认为这个函数可以接受任意数量的参数,lodash的curry会默认认为它不需要参数,所以会立即执行:
// 计算所有传入数字的和,用剩余参数接收 const sumAll = (...nums) => nums.reduce((total, num) => total + num, 0); // 直接用_.curry,会立即执行 const curriedSum = _.curry(sumAll); console.log(curriedSum()); // 输出0,直接执行了,根本没返回柯里化函数! // 手动指定arity=3,告诉lodash我们要收集3个参数才执行 const curriedSumWithArity = _.curry(sumAll, 3); const addTwoMore = curriedSumWithArity(10); const addOneMore = addTwoMore(20); console.log(addOneMore(30)); // 输出60,符合柯里化预期
场景2:带默认参数的函数
当函数有默认参数时,func.length只会统计到第一个带默认值的参数之前的参数数量,这会和我们实际想要的参数个数不符:
// 第二个参数有默认值,func.length=1(只有第一个参数没有默认值) const greet = (name, greeting = 'Hello') => `${greeting}, ${name}!`; // 直接curry的话,lodash认为只需要1个参数就执行 const curriedGreet = _.curry(greet); console.log(curriedGreet('Alice')); // 直接输出"Hello, Alice!",没有返回等待greeting的函数 // 指定arity=2,明确告诉lodash需要两个参数才触发执行 const curriedGreetWithArity = _.curry(greet, 2); const greetWithHi = curriedGreetWithArity('Hi'); console.log(greetWithHi('Bob')); // 输出"Hi, Bob!",完美实现柯里化
场景3:解构参数的函数
用对象解构或数组解构作为参数时,func.length同样会是0,这时候也必须指定arity:
// 解构参数,func.length=0 const getUserFullName = ({ firstName, lastName }) => `${firstName} ${lastName}`; // 直接curry会立即执行,返回空字符串(因为解构了空对象) const curriedGetName = _.curry(getUserFullName); console.log(curriedGetName()); // 输出" " // 指定arity=1,告诉lodash需要接收1个对象参数才执行 const curriedGetNameWithArity = _.curry(getUserFullName, 1); const getSmithFullName = curriedGetNameWithArity({ lastName: 'Smith' }); console.log(getSmithFullName({ firstName: 'John' })); // 输出"John Smith"
本质原因是:_.curry默认依赖函数的length属性来判断需要收集多少个参数才执行原函数,但当函数使用剩余参数、默认参数、解构参数时,length属性无法准确反映我们实际期望的参数数量,这时候就必须手动指定arity来修正这个判断。
内容的提问来源于stack exchange,提问作者bazeblackwood
相关产品推荐
相关产品推荐

