78 lines
3.4 KiB
Plaintext

== Why is this an issue?
Ignoring function parameters or overwriting them with a new value without reading them can lead to confusion and errors in the code. Developers won't be able to tell whether the original parameter or some temporary variable is being accessed without going through the whole function. It may indicate that the function is not properly designed or that there is a mistake in the code.
Moreover, some developers might also expect assignments of function parameters to be visible to callers, which is not the case. Arguments are always passed by value and never passed by reference. If a function reassigns a parameter, the value won't change outside the function. It is not possible to simulate an assignment on that variable in the caller's scope. However, objects are passed by value to their reference (https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing[passed by sharing]), which means if the object's properties are mutated, the change will impact the outside of the function.
The same logic applies to caught exceptions and variable declarations inside ``++for...in++`` and ``++for...of++`` statements: their initial values should not be ignored.
[source,javascript,diff-id=1,diff-type=noncompliant]
----
function myFunction(name, strings) {
name = foo; // Noncompliant: initial value of 'name' is ignored
for (let str of strings) {
str = ""; // Noncompliant: initial value of 'str' is ignored
}
}
----
Function parameters, caught exceptions, and variables initialized in ``++for...in++`` and ``++for...of++``statements should be read at least once before reassigning them. If they do not need to be read, the code should be refactored to avoid confusion.
[source,javascript,diff-id=1,diff-type=compliant]
----
function myFunction(name, strings) {
const nameCopy = name;
name = foo;
for (let str of strings) {
const strCopy = str;
str = "";
}
}
----
=== Exceptions
There is a common pattern in JavaScript to overwrite certain parameters depending on other parameters that are optional. For example, a callback is, by convention, always passed in the last position. If a parameter in a previous position was not passed, the callback will be passed in its position instead.
Therefore, the rule ignores parameter reassignments that are inside an `if` statement block.
[source,javascript]
----
function myFunction(param, optionalParam, cb) {
if (typeof optionalParam === 'function') {
cb = optionalParam;
optionalParam = {};
}
}
----
== Resources
=== Documentation
* MDN web docs - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions[Functions]
* MDN web docs - link:++https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch#catch_binding++[Catch binding]
* MDN web docs - link:++https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of++[``++for...of++``]
* MDN web docs - link:++https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in++[``++for...in++``]
* Wikipedia - https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing[Call by sharing]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
include::../message.adoc[]
include::../highlighting.adoc[]
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]