求助:柯里化multiply函数调用报错TypeError,如何实现链式相乘?
问题:柯里化multiply函数报错及功能实现问题
运行代码时遇到错误:Uncaught TypeError TypeError: multipliers.reduce(...) is not a function。
我正在研究柯里化(currying)与部分应用(partial application),期望multiply函数能通过multipliers数组正确调用。需要实现的multiply函数需以特殊方式相乘整数:函数的返回值可被反复调用,直到传入无参数时返回最终乘积。例如multiply(3)(4)(5)()应返回3 * 4 * 5 = 60。我使用辅助函数solution(multipliers)接收所有乘数,并按上述方式传递给multiply。
输入:
multipliers: [3, 4, 5]
输出:
60
代码:
function multiply(x) { return function(y) { // anonymous function return function(z) { // anonymous function return x * y * z; } } } // this function lets you invoke something like multiply(3)(4)(5)() with dynamic arguments function solution(multipliers) { return (multipliers.reduce((prev, arg) => { if (prev) { return prev(arg); } return multiply(arg); }, null))(); } console.log(solution([3, 4, 5]));
解答
问题分析
- multiply函数的核心缺陷:当前的
multiply是固定三层嵌套的硬编码函数,只能处理最多三个参数的调用,且完全没有实现“无参数调用返回乘积”的逻辑。当调用multiply(3)(4)(5)时,直接返回的是数值60而非可继续调用的函数,后续solution里对这个数值执行()调用,自然会触发“不是函数”的类型错误。 - 错误本质:你看到的报错提示,根源是
reduce最终返回的是一个数值,而非预期的可调用函数,对数值执行函数调用操作违反了类型规则。
修正方案
重构multiply函数,让它支持任意次数的参数链式调用,直到无参数传入时返回乘积:
function multiply(x) { // 维护内部乘数列表 const multipliers = [x]; // 返回可复用的调用函数 const next = function(y) { // 有参数时,添加到列表并继续返回自身 if (arguments.length > 0) { multipliers.push(y); return next; } // 无参数时计算总乘积 return multipliers.reduce((total, num) => total * num, 1); }; return next; } function solution(multipliers) { return multipliers.reduce((prev, arg) => { if (prev) { return prev(arg); } return multiply(arg); }, null)(); } console.log(solution([3, 4, 5])); // 输出60
修正说明
- 重构后的
multiply通过内部数组存储所有传入的乘数,每次调用传入参数时,就将参数加入数组并返回自身,实现无限次链式调用。 - 当调用时不传入参数(通过
arguments.length判断),就用reduce计算数组内所有数的乘积并返回。 - 这样
multiply(3)(4)(5)()能正确返回60,solution的逻辑也能正常执行,不会再触发类型错误。
内容的提问来源于stack exchange,提问作者imparante
相关产品推荐
相关产品推荐

