TypeScript类中拆分的Reducer函数报错,如何使其正常工作?
问题原因与解决方案
问题根源
当你把sumInventoriesReducer作为参数传递给Array.reduce()时,函数的this绑定会丢失。reduce调用回调函数时,默认不会保留原函数的this上下文(严格模式下this会变成undefined),所以在sumInventoriesReducer里访问this.sumCalories会抛出TypeError。
解决方案
以下三种方式都能解决这个问题,适配你的OOP实现需求:
方案1:用箭头函数包裹reducer调用
在reduce中用箭头函数包裹对sumInventoriesReducer的调用,箭头函数会继承当前上下文的this,确保指向CalorieCounter类:
export default class CalorieCounter { public static calculateMaxInventoryValue(elfInventories: number[][]): number { // 用箭头函数包裹,保留this绑定 return Math.max(...elfInventories.reduce((acc, element) => this.sumInventoriesReducer(acc, element), [])); } private static sumInventoriesReducer( acc: number[], element: number[] ): number[] { return [...acc, this.sumCalories(element)]; } private static sumCalories(inventory: number[]): number { return inventory.reduce((a: number, b: number) => a + b, 0); } }
方案2:绑定this到reducer函数
通过Function.bind()把this显式绑定到sumInventoriesReducer,确保函数调用时this指向CalorieCounter:
export default class CalorieCounter { public static calculateMaxInventoryValue(elfInventories: number[][]): number { // 绑定this到当前类 return Math.max(...elfInventories.reduce(this.sumInventoriesReducer.bind(this), [])); } private static sumInventoriesReducer( acc: number[], element: number[] ): number[] { return [...acc, this.sumCalories(element)]; } private static sumCalories(inventory: number[]): number { return inventory.reduce((a: number, b: number) => a + b, 0); } }
方案3:直接用类名调用静态方法(推荐)
因为sumCalories是静态方法,直接用CalorieCounter.sumCalories代替this.sumCalories,完全规避this绑定问题,代码更直观:
export default class CalorieCounter { public static calculateMaxInventoryValue(elfInventories: number[][]): number { return Math.max(...elfInventories.reduce(this.sumInventoriesReducer, [])); } private static sumInventoriesReducer( acc: number[], element: number[] ): number[] { // 直接通过类名调用静态方法,无需依赖this return [...acc, CalorieCounter.sumCalories(element)]; } private static sumCalories(inventory: number[]): number { return inventory.reduce((a: number, b: number) => a + b, 0); } }
内容的提问来源于stack exchange,提问作者Jackematics
相关产品推荐
相关产品推荐

