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

IT技术 javascript dom eslint
2021-02-26 04:04:43

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

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

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

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

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

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

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

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

6个回答

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

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

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

"rules": {
  "no-param-reassign": [2, { "props": false }]
}

或者,您可以禁用该功能的规则

/* eslint-disable no-param-reassign */
function (el) {
  el.expando = {};
}
/* eslint-enable no-param-reassign */

或仅针对该行

function (el) {
  el.expando = {}; // eslint-disable-line no-param-reassign
}
如果问题仅在于问题中所述的设置函数参数的属性,那么下面 Gyandeep 的回答要好得多。
2021-04-29 04:04:43
谢谢你。似乎大多数人发现修改 linter 是最好的方法。对我来说,将它应用于单行似乎是最好的权衡。
2021-05-06 04:04:43
谢谢@hiehiuehue:看起来他们把它拿下来了。删除链接。
2021-05-10 04:04:43
这确实是有意义的,即表达的NodeJS项目,其中有时你可能需要修改res.session直线距离
2021-05-15 04:04:43

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

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

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

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

规则文档中暗示了这种方法

此规则的正确代码示例:

/*eslint no-param-reassign: "error"*/

function foo(bar) {
    var baz = bar;
}

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

您在这里试图避免的“问题”实际上并不是问题。arguments永远不应该使用这个对象。相反,您应该使用rest parameters因此可以安全地忽略 no-param-reassign 。
2021-04-18 04:04:43
您可能会收到“局部变量‘theElement’是多余的”。
2021-04-22 04:04:43
这个答案应该是公认的答案,因为它指向官方文档并且得到了很好的解释。大多数其他答案就像关闭火警!
2021-04-30 04:04:43
修改参数的属性不会改变该参数所指的内容。,我以为对象是通过引用传递的!请您详细说明一下好吗?
2021-05-05 04:04:43
这应该是公认的答案,而不是规避行为的方法。由于这个答案以及官方 ESLint 文档中所述的 Patric Bacon 指出了在某些情况下可能会发生的明显问题:spin.atomicobject.com/2011/04/10/...
2021-05-17 04:04:43

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

{
    "rules": {
        "no-param-reassign": [2, { 
            "props": false
        }]
    },
    "extends": "eslint-config-airbnb"
}

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

这个答案不完全包含在接受的答案中吗?
2021-04-25 04:04:43
@DanDascalescu 在接受的答案下面有一条评论指向这个,所以也许在某个时候对其进行了编辑以使其更全面?
2021-04-25 04:04:43

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

但是,要解决此问题,您还可以使用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
});
function (el) {
  el.setAttribute('expando', {});
}

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