-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rule suggestion: Avoid modifying object references #1600
Comments
👍 * 1000. This would be very useful for me. |
Good idea. New rules are low priority right now, but we are open to contributions. |
Great proposal, this rule would help distinguishing pure functions from the ones with unintented side effects. |
From @sindresorhus: I don't have a concrete solution for this, but I'm going to elaborate on the problem. ProblemI make a node module. The main export takes an input and some options as an object: module.exports = function (input, options) {
return options.foo == 'unicorn' ? input.split('/') : input;
}; The module does something with the input based on these options. The problem is when the module matures and gets more functionality: module.exports = function (input, options) {
options.foo = options.bar === true ? 'unicorn' : 'cake';
return options.foo ? input.split('/') : input;
}; As you might notice, we're now suddenly modifying the user supplied object. The change looks harmless, but what if the user uses the same object for multiple invocations. It's an easy mistake to make, but can result in some really hard to track down bugs. I've seen this mistake made in countless of modules and code. Even just today. Correct wayThe correct solution here is using some kind of extend method like var objectAssign = require('object-assign');
module.exports = function (input, options) {
options = objectAssign({}, options);
options.foo = options.bar === true ? 'unicorn' : 'cake';
return options.foo ? input.split('/') : input;
}; DiscussI was hoping we could discuss what ESLint can do to help with this. |
I will work on this. I will add an option to {
"no-param-reassign": [2, {"props": true}]
} To start, I will not support the following pattern: function foo3 (bar) {
var temp = bar.thisPropertyAlreadyExisted;
temp.deepProperty = somethingElse;
} I guess this pattern needs execution path analysis... How is this thought? |
@nzakas above post from @sindresorhus , the correct solution doesn't actually solve the problem since its a shallow copy. |
Yup, it looks a seed of a rule, but I guess very difficult to make... |
I'd say don't worry about anything that needs path analysis. Just doing a basic check is good enough to start. |
Update: `props` option of `no-param-reassign` (fixes #1600)
Is there any way to get the |
In my opinion it is generally dangerous to change the input parameter of a function if it is not a primitive type. It could e.g. result in side effects that are hard to debug because the referenced object is changed in the function.
While I think we won't be able to detect every possible fault, I suggest creating a rule that at least catches the simple case:
What do you think about this?
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: