Javascript 几个小的减少和一个大的减少?
使用Javascript 几个小的减少和一个大的减少?,javascript,arrays,typescript,flowtype,Javascript,Arrays,Typescript,Flowtype,使用reduce: addSales(sales: Sale[]) { this.total += sales.reduce((ac, sale) => ac + sale.total, 0); this.tax += sales.reduce((ac, sale) => ac + sale.tax, 0); this.discount += sales.reduce((ac, sale) => ac + sale.discount, 0); this.qty
reduce
:
addSales(sales: Sale[]) {
this.total += sales.reduce((ac, sale) => ac + sale.total, 0);
this.tax += sales.reduce((ac, sale) => ac + sale.tax, 0);
this.discount += sales.reduce((ac, sale) => ac + sale.discount, 0);
this.qty += sales.reduce((ac, sale) => ac + sale.qty, 0);
}
使用.forEach
addSales(sales: Sale[]) {
sales.forEach(sale => {
this.total += sale.total;
this.tax += sale.tax;
this.discount += sale.discount;
this.qty += sale.qty;
});
}
在这里使用.forEach
似乎更具可读性,而且性能可能更好,因为它只会在其中循环一次
但从长远来看,它是否会降低模块化程度?我的代码中有一些部分是从较小的.forEach
块开始的,但随着时间的推移,它的大小逐渐增大,并且不知何故难以重构,因为它们彼此“绑定”在一起
你能分享一下你在这方面的经验吗?在这里使用
forEach
没有什么错,而且肯定比多次调用reduce
效率更高(尽管程度可以忽略不计,除非sales
可以包含大量if值)。正如你提到的,它也更具可读性
您可以将this
传递给reduce
作为种子,并一起进行所有更改,但由于代码正在改变实例,因此使用更具功能性的方法无法获得多少好处
我会坚持使用forEach。Richard的答案很好,但是如果你想坚持使用
reduce
来避免尽管是局部的变异,你可以这样做,同时仍然只访问每个对象一次。事实上,reduce
的美妙之处在于,我们可以将数组转换为我们想要的任意值,所以让我们从中获得乐趣
export function tallySales(sales: Sale[]) {
return sales.reduce((ac, {total, tax, discount, qty}) => ({
total: ac.total + total,
tax: ac.tax + tax,
discount: ac.discount + discount,
qty: ac.qty + qty
}), {total: 0, tax: 0, discount: 0, qty: 0});
关于模块化的具体问题,使用上述风格绝不是更模块化,但它确实鼓励我们编写更多的可测试代码,因为我们用函数的输入和输出来表达东西。上面的函数可以很容易地进行测试,而改变类实例动态绑定的命令式版本测试起来更为复杂,尽管在本例中不一定要测试很多
有趣的是,它根本不是关于使用reduce
而不是forEach
。事实上,上面的函数可以用forEach
编写,它将像reduce
一样具有可维护性、可测试性和模块化。它更多地关系到如何使用reduce
让我们进入用值来表达接口的思维框架,而不是修改与许多生产者和消费者相关的状态,从而隐式地推进程序