为什么这个reducer函数在typescript类中不起作用?我能让它起作用吗?

4dbbbstv  于 2022-12-05  发布在  TypeScript
关注(0)|答案(2)|浏览(213)

在今年的第一次代码挑战中,我一直在使用reducer,这段代码工作得很好:

export default class CalorieCounter {
  public static calculateMaxInventoryValue(elfInventories: number[][]): number {
    const sumInventoriesReducer = (
      acc: number[],
      element: number[]
    ): number[] => [...acc, this.sumCalories(element)];

    return Math.max(...elfInventories.reduce(sumInventoriesReducer, []));
  }

  private static sumCalories(inventory: number[]): number {
    return inventory.reduce((a: number, b: number) => a + b, 0);
  }
}

然后,我尝试将sumInventoriesReducer拆分到同一个类中它自己的私有函数中。

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[] {
    return [...acc, this.sumCalories(element)];
  }

  private static sumCalories(inventory: number[]): number {
    return inventory.reduce((a: number, b: number) => a + b, 0);
  }
}

逻辑是完全相同的,所有的变化是它作为一个私有函数传入(它是静态的事实不是原因,在没有静态的情况下尝试它,得到了同样的错误)。
这是错误:

TypeError: Cannot read property 'sumCalories' of undefined

      20 |     element: number[]
      21 |   ): number[] {
    > 22 |     return [...acc, this.sumCalories(element)];
         |                          ^
      23 |   }
      24 |
      25 |   private static sumCalories(inventory: number[]): number {

如果可以的话我想用面向对象的方式来做这个,注意到reducer是函数式编程的一个主要部分,但是我觉得我应该能够用一个私有类函数来完成这个工作,有人能帮忙吗?

goucqfw6

goucqfw61#

问题在于,您试图访问静态方法(只存在于类中,而不存在于原型中)中的示例属性(只存在于调用constructor()之后)。
调用constructor()方法后,关键字this具有instance对象的值,但如果在静态方法中引用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[] {
    return [...acc, this.sumCalories(element)]; // The problem is here
  }

  private static sumCalories(inventory: number[]): number {
    return inventory.reduce((a: number, b: number) => a + b, 0);
  }
}

如果要保留此架构,只需更新该行,使其

  • 起始日期:this.sumCalories(element)
  • to:CalorieCounter.sumCalories(element)通过这样做,您将从类本身而不是从不存在的示例访问方法。

生成的代码为:

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[] {
    return [...acc, CalorieCounter.sumCalories(element)]; // The problem is here
  }

  private static sumCalories(inventory: number[]): number {
    return inventory.reduce((a: number, b: number) => a + b, 0);
  }
}

如上所述,calculateMaxInventoryValue方法也是静态的,但它尝试访问示例方法,通过更正它,代码将变为:

export default class CalorieCounter {
  public static calculateMaxInventoryValue(elfInventories: number[][]): number {
    return Math.max(...elfInventories.reduce(CalorieCounter.sumInventoriesReducer, []));
  }

  private static sumInventoriesReducer(
    acc: number[],
    element: number[]
  ): number[] {
    return [...acc, CalorieCounter.sumCalories(element)]; // The problem is here
  }

  private static sumCalories(inventory: number[]): number {
    return inventory.reduce((a: number, b: number) => a + b, 0);
  }
}
gfttwv5a

gfttwv5a2#

这是因为你没有展平this.sumCalories(element)
this.sumCalories(element)返回一个number[],所以你需要用三个点把它展平。
如果你写return [...acc, ...this.sumCalories(element)];,它应该可以工作。

相关问题