Javascript 在 DOM 对象上设置属性时如何避免无参数重新分配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35637770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:03:16  来源:igfitidea点击:

How to avoid no-param-reassign when setting a property on a DOM object

javascriptdomeslint

提问by Lukas

I have a method which's main purpose is to set a property on a DOM object

我有一个主要目的是在 DOM 对象上设置属性的方法

function (el) {
  el.expando = {};
}

I use AirBnB's code style which makes ESLint throw a no-param-reassignerror:

我使用 AirBnB 的代码风格,这使得 ESLint 抛出no-param-reassign错误:

error Assignment to function parameter 'el' no-param-reassign

错误分配给函数参数 'el' no-param-reassign

How can I manipulate a DOM object passed as an argument while conforming AirBnB's code style?

如何在符合 AirBnB 的代码风格的同时操作作为参数传递的 DOM 对象?

Somebody suggested to use /* eslint react/prop-types: 0 */referring to another issuebut if I am not mistaken this applies well for react, but not for native DOM manipulation.

有人建议使用/* eslint react/prop-types: 0 */引用另一个问题,但如果我没记错的话,这适用于反应,但不适用于本机 DOM 操作。

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.

我也不认为改变代码风格是一个答案。我相信使用标准风格的好处之一是在项目中拥有一致的代码,随意更改规则感觉就像滥用了像 AirBnB 这样的主要代码风格。

For the record, I asked AirBnB on GitHub, what they think is the way to go in these cases in issue #766.

作为记录,我在 GitHub 上询问了 AirBnB,他们认为在 issue #766中这些情况下的方法是什么。

回答by sfletche

As @Mathletics suggests, you can disable the ruleentirely by adding this to your .eslintrc.jsonfile:

正如@Mathletics 所建议的,您可以通过将其添加到您的文件中来完全禁用该规则.eslintrc.json

"rules": {
  "no-param-reassign": 0
}

Or you could disable the rule specifically for param properties

或者您可以禁用专门针对 param 属性的规则

"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 poston disabling ESLint rules specifically to accommodate AirBnB's style guide.

您还可以查看这篇 关于禁用 ESLint 规则的博客文章,专门用于适应 AirBnB 的风格指南。

回答by Useless Code

As this article explains, this rule is meant to avoid mutating the argumentsobject. If you assign to a parameter and then try and access some of the parameters via the argumentsobject, it can lead to unexpected results.

正如本文所述,此规则旨在避免改变arguments对象。如果您分配给一个参数,然后尝试通过该arguments对象访问某些参数,则可能会导致意外结果。

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:

您可以通过使用另一个变量来获取对 DOM 元素的引用,然后对其进行修改,从而保持规则不变并保持 AirBnB 样式:

function (el) {
  var theElement = el;
  theElement.expando = {};
}

In JS objects (including DOM nodes) are passed by reference, so here eland theElementare references to the same DOM node, but modifying theElementdoesn't mutate the argumentsobject since arguments[0]remains just a reference to that DOM element.

在 JS 中对象(包括 DOM 节点)是通过引用传递的,所以这里eltheElement是对同一个 DOM 节点的引用,但修改theElement不会改变arguments对象,因为它arguments[0]仍然只是对该 DOM 元素的引用。

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.

就个人而言,我只会使用"no-param-reassign": ["error", { "props": false }]提到的其他几个答案的方法。修改参数的属性不会改变该参数所指的内容,也不应该遇到此规则试图避免的问题。

回答by Gyandeep

You can override this rule inside your .eslintrcfile and disable it for param properties like this

您可以在.eslintrc文件中覆盖此规则,并为这样的参数属性禁用它

{
    "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

这种方式规则仍然有效,但不会对属性发出警告。更多信息:http: //eslint.org/docs/rules/no-param-reassign

回答by Justus Romijn

The no-param-reassignwarning makes sense for common functions, but for a classic Array.forEachloop over an array which you intend to mutate it isn't to appropriate.

no-param-reassign警告对于常见函数是有意义的,但对于Array.forEach您打算改变它的数组的经典循环来说是不合适的。

However, to get around this, you can also use Array.mapwith a new object (if you are like me, dislike snoozing warnings with comments):

但是,为了解决这个问题,您还可以使用Array.map新对象(如果您像我一样,不喜欢带有注释的暂停警告):

someArray = someArray.map((_item) => {
    let item = Object.assign({}, _item); // decouple instance
    item.foo = "bar"; // assign a property
    return item; // replace original with new instance
});

回答by RH Becker

Those wishing to selectively deactivate this rule might be interested in a proposed new optionfor the no-param-reassignrule that would allow a "white list" of object names with respect to which parameter reassignment should be ignored.

那些希望选择停用此规则可能会感兴趣的提出了新的选项no-param-reassign,将允许对象名称的“白名单”相对于该参数重新分配应该被忽略的规则。

回答by Victor Santos

Following the documentation:

按照文档

function (el) {
  const element = el
  element.expando = {}
}

回答by Viktor Antishov

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

您可以使用方法来更新数据。例如。“res.status(404)”而不是“res.statusCode = 404”我找到了解决方案。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;
});

回答by Jazzy

You can also use lodash assignInwhich mutates the object. assignIn(obj, { someNewObj });

您还可以使用 lodashassignIn来改变对象。 assignIn(obj, { someNewObj });

https://lodash.com/docs/4.17.2#assignIn

https://lodash.com/docs/4.17.2#assignIn

回答by avalanche1

function (el) {
  el.setAttribute('expando', {});
}

Everything else is just ugly hacks.

其他一切都只是丑陋的黑客。

回答by Oliver

You can use:

您可以使用:

(param) => {
  const data = Object.assign({}, param);
  data.element = 'some value';
}