为什么这个reducer函数不能在typescript类中工作,我能使它工作吗?



在今年的第一次代码挑战中,我一直在摆弄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是函数式编程的主要内容,但我觉得我应该能够使用私有类函数来完成这项工作。有人能帮忙吗?

问题是您试图访问静态方法(仅存在于类而不存在于原型)中的实例属性(仅在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);
}
}

如果你想保留这个模式你可以把这行改成

  • from:this.sumCalories(element)
  • :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);
}
}

这是因为你没有把this.sumCalories(element)压平。

this.sumCalories(element)返回一个number[],所以你需要用三个点把它压平。

如果你写return [...acc, ...this.sumCalories(element)];它应该工作。

最新更新