JavaScript中reduce回调为何可省略参数?错误原因及编程范式名称
JavaScript reduce 常见问题解答
先看示例代码:
const nums = [1, 2, 3] const sumNumbers = (sum, num) => sum + num // WORKS! let a = nums.reduce(sumNumbers, 0) // ERROR! let b = nums.reduce(sumNumbers(sum, num), 0)
问题1:为何在JavaScript的reduce方法中,回调函数可以省略参数?
JavaScript的函数参数机制是动态的,函数定义的形参数量和调用时传入的实参数量不需要严格匹配。reduce方法内部会固定给回调函数传入4个参数:累加值、当前元素、当前索引、原数组。但你只需要用到前两个参数时,完全可以只定义这两个形参——剩下的参数会被自动忽略,不会影响函数执行。哪怕你一个参数都不定义,函数也能正常运行,只是无法访问那些未定义的参数值而已。
问题2:直接在reduce中调用sumNumbers(sum, num)时,为什么会触发“ReferenceError: sum is not defined”错误?
这里核心是搞混了传递函数引用和直接调用函数的区别:
nums.reduce(sumNumbers, 0):这里传入的是sumNumbers函数本身的引用,reduce会在遍历数组的过程中自动调用这个函数,并把它需要的累加值、当前元素等参数传进去。sumNumbers(sum, num):这是你主动调用sumNumbers函数,但此时sum和num这两个变量根本没有被定义过,所以JS引擎会抛出引用错误。退一步说,就算你提前定义了这两个变量,这么做的结果是把sumNumbers的返回值(一个数字)传给reduce,但reduce要求第一个参数必须是函数类型的回调,后续还会抛出“不是函数”的错误。
问题3:这种将函数作为参数传递的编程方式是否有特定名称?
这种方式属于高阶函数的应用场景,而整个编程范式属于函数式编程:
- 高阶函数指的是可以接收函数作为参数,或者返回函数的函数,
reduce本身就是一个典型的高阶函数。 - 你传递的
sumNumbers在这里被称为回调函数(callback function)——即由另一个函数(这里是reduce)在合适时机调用的函数。
内容的提问来源于stack exchange,提问作者Hector
相关产品推荐
相关产品推荐

