可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a method which's main purpose is to set a property on a DOM object
function (el) {
el.expando = {};
}
I use AirBnB's code style which makes ESLint throw a no-param-reassign
error:
error Assignment to function parameter 'el' no-param-reassign
How can I manipulate a DOM object passed as an argument while conforming AirBnB's code style?
Somebody suggested to use /* eslint react/prop-types: 0 */
referring to another issue but if I am not mistaken this applies well for react, but not for native DOM manipulation.
Also I do not think changing the code style is an answer. I believe one of the benefits of using a standard style is having consistent code across projects and changing the rules at will feels like a misuse of a major code style like AirBnB's.
For the record, I asked AirBnB on GitHub, what they think is the way to go in these cases in issue #766.
回答1:
As @Mathletics suggests, you can disable the rule entirely by adding this to your .eslintrc.json
file:
"rules": {
"no-param-reassign": 0
}
Or you could disable the rule specifically for param properties
"rules": {
"no-param-reassign": [2, { "props": false }]
}
Alternatively, you could disable the rule for that function
/* eslint-disable no-param-reassign */
function (el) {
el.expando = {};
}
/* eslint-enable no-param-reassign */
Or for that line only
function (el) {
el.expando = {}; // eslint-disable-line no-param-reassign
}
You might also check out this blog post on disabling ESLint rules specifically to accommodate AirBnB's style guide.
回答2:
As this article explains, this rule is meant to avoid mutating the arguments
object. If you assign to a parameter and then try and access some of the parameters via the arguments
object, it can lead to unexpected results.
You could keep the rule intact and maintain the AirBnB style by using another variable to get a reference to the DOM element and then modify that:
function (el) {
var theElement = el;
theElement.expando = {};
}
In JS objects (including DOM nodes) are passed by reference, so here el
and theElement
are references to the same DOM node, but modifying theElement
doesn't mutate the arguments
object since arguments[0]
remains just a reference to that DOM element.
This approach is hinted at in the documentation for the rule:
Examples of correct code for this rule:
/*eslint no-param-reassign: "error"*/
function foo(bar) {
var baz = bar;
}
Personally, I would just use the "no-param-reassign": ["error", { "props": false }]
approach a couple of other answers mentioned. Modifying a property of the parameter doesn't mutate what that parameter refers to and shouldn't run into the kinds of problems this rule is trying to avoid.
回答3:
You can override this rule inside your .eslintrc
file and disable it for param properties like this
{
"rules": {
"no-param-reassign": [2, {
"props": false
}]
},
"extends": "eslint-config-airbnb"
}
This way rule is still active but it will not warn for properties.
More info: http://eslint.org/docs/rules/no-param-reassign
回答4:
The no-param-reassign
warning makes sense for common functions, but for a classic Array.forEach
loop over an array which you intend to mutate it isn't to appropriate.
However, to get around this, you can also use Array.map
with a new object (if you are like me, dislike snoozing warnings with comments):
someArray = someArray.map((_item) => {
let item = Object.assign({}, _item); // decouple instance
item.foo = "bar"; // assign a property
return item; // replace original with new instance
});
回答5:
Those wishing to selectively deactivate this rule might be interested in a proposed new option for the no-param-reassign
rule that would allow a "white list" of object names with respect to which parameter reassignment should be ignored.
回答6:
Following the documentation:
function (el) {
const element = el
element.expando = {}
}
回答7:
You can also use lodash assignIn
which mutates the object.
assignIn(obj, { someNewObj });
https://lodash.com/docs/4.17.2#assignIn
回答8:
You can use methods for updating data. Eg. "res.status(404)" instead of "res.statusCode = 404"
I found the solution. https://github.com/eslint/eslint/issues/6505#issuecomment-282325903
/*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsFor": ["$scope"] }]*/
app.controller('MyCtrl', function($scope) {
$scope.something = true;
});
回答9:
function (el) {
el.setAttribute('expando', {});
}
Everything else is just ugly hacks.
回答10:
You can use:
(param) => {
const data = Object.assign({}, param);
data.element = 'some value';
}