no-param-reassign - Array.prototype.reduce and alike exceptions
See original GitHub issueHi and thanks everybody who participated on no-param-reassign
!
I know, this is a duplicate of #8007 and #6339. This is a lobby.
Summary
no-param-reassign
is pretty useful rule. I’m not breaking this rule all time except if I write code using this perfect function:
Array.prototype.reduce
(
function
(accumulator, currentValue) => accumulator, initialAccumulator )
Currently there is no way to hint no-param-reassign
rule to relax reduce
function accumulator in perfectly finest way.
tl;dr
I really ❤️ no-param-reassign
rule. But there is at least one edge case where assigning to passed variable is perfectly fine, possibly the best way to write it down — someArray.reduce()
function.
I’m sure that everyone knows this function, using it time to time for transforming data from one shape to another.
I see misunderstanding of reduce
with no-param-reassign
rule leading to wasting a lot of resources. It is so simple. Just use spread operator for copying result of previous iteration:
// this code is perfectly fine, but violates rule:
const firstNameCount = users.reduce((firstNameCount, user) => {
firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1;
return firstNameCount;
}, {});
// this code is performing poorly, wasting memory and CPU, but fits rule :-(
const firstNameCount = users.reduce((acc, user) => {
const result = { ...acc };
result[user.firstName] = (acc[user.firstName] || 0) + 1;
return result;
}, {});
This use case is so special and simple that there is no need for more similar functions. This is the pattern in fact. A coding primitive, so special that famous framework Redux is mostly about thinking about this one function, deriving all the possibilities from using this pattern!
If you need more…
This is so special case that it can have it’s own syntax, but, you know, this is not needed in javascript. But I can imagine language expression construct like this:
reduce <Iterable> into <lvalue> [ = <rvalue> ] with <identifier> [, <identifier>] as <statement using <lvalue> >
To be more concrete:
const firstNameCount = users.reduce((firstNameCount, user) => {
firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1;
return firstNameCount;
}, {});
can be written like this:
const firstNameCount = reduce users into firstNameCount = {} with user as {
firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1;
}
const firstNameCount = reduce users into firstNameCount = {} with user [, index] as { firstNameCount[user.firstName] = (firstNameCount[user.firstName] || 0) + 1; }
PS: This is only illustrative example of language construct! I cannot imagine language except Pascal which want introduce this… 😄
Is Array.prototype.reduce
only exception?
I thing no. But I percept it as language primitive so it should be only default exception.
Issue Analytics
- State:
- Created 6 years ago
- Comments:7 (5 by maintainers)
Top GitHub Comments
This would also apply to
reduceRight
, however the problem with creating such enhancement is that we don’t know if you are callingreduce
on the array, or on your custom made object. We don’t track variable types in ESLint, so we don’t really have a good way to figure out if the currentreduce
function should be excluded or not.For anyone who is just looking for the quick solution, this is how you disable the warning: