
100
|
第
4
章
内部构造
这种类型的操作应该设计得非常明确以防混淆,不过还是要尽可能避免这
种操作。如果认为函数就是输入与输出之间的方程式,这种不明智的想法
会带来很多负面影响。在函数体内修改输入就是其中一个例子,这样做可
能引入
bug
,令人困惑,而且难以追踪这些修改的源头。
我们经常能看到一些修改输入参数然后返回这些参数的函数。这在使用
Array#map
回调时较为常见,开发者想要修改列表中每个对象的一两个属性,
但还让原来的对象作为集合中的元素,如以下代码所示 :
movies.map(movie => {
movie.profit = movie.gross - movie.budget
return movie
})
在这些情况中,最好避免同时使用
Array#map
,而是使用
Array#forEach
或
者
for..of
,如下所示 :
for (const movie of movies) {
movie.profit = movie.gross - movie.budget
}
假设你想用类似“票房收入大于
1500
万美元”的条件过滤
movies
,但是
Array#forEach
和
for..of
都不支持链式调用,它们是纯粹的循环,不产
生任何输出。不过,这是一个好问题,因为它将
movie
层级的数据变化和
movies
层级的数据转换做了显式分离。在
movie
层级,我们给
movies
中的
每一项增加了一个
profit
属性,而在
movies
层级,我们希望产生一个全新
的只包含高票房电影的集合 :