在今年的第一次代码挑战中,我一直在摆弄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)];
它应该工作。