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

Luk*_*kas 75 javascript dom eslint

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

function (el) {
  el.expando = {};
}
Run Code Online (Sandbox Code Playgroud)

我使用AirBnB的代码样式使ESLint抛出no-param-reassign错误:

错误赋值函数参数'el'no-param-reassign

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

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

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

为了记录,我在GitHub上询问了AirBnB,他们认为在问题#766中这些问题的出路是什么.

sfl*_*che 88

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

"rules": {
  "no-param-reassign": 0
}
Run Code Online (Sandbox Code Playgroud)

或者您可以专门为param属性禁用规则

"rules": {
  "no-param-reassign": [2, { "props": false }]
}
Run Code Online (Sandbox Code Playgroud)

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

/* eslint-disable no-param-reassign */
function (el) {
  el.expando = {};
}
/* eslint-enable no-param-reassign */
Run Code Online (Sandbox Code Playgroud)

或仅限该行

function (el) {
  el.expando = {}; // eslint-disable-line no-param-reassign
}
Run Code Online (Sandbox Code Playgroud)

您还可以查看此博客文章 ,专门禁用ESLint规则以适应AirBnB的样式指南.

  • 这真的很有意义,即对于 nodejs express 项目,有时你可能想直接修改 `res.session` (2认同)

Use*_*ode 59

正如本文所解释的,此规则旨在避免变异arguments对象.如果您指定参数然后尝试通过arguments对象访问某些参数,则可能会导致意外结果.

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

function (el) {
  var theElement = el;
  theElement.expando = {};
}
Run Code Online (Sandbox Code Playgroud)

在JS对象(包括DOM节点)通过引用传递,所以这里eltheElement是相同的DOM节点的引用,但修改theElement不发生变异的arguments,因为对象arguments[0]遗体只是到DOM元素的引用.

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

此规则的正确代码示例:

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

function foo(bar) {
    var baz = bar;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这应该是公认的答案,而不是规避行为的方法。自从这个答案以来,ESLint官方文档中所述的Patric Bacon指出了在某些情况下可能发生的明显问题:https://spin.atomicobject.com/2011/04/10/javascript-don-t-重新分配您的功能参数/ (5认同)
  • 这个答案应该是公认的答案,因为它指向官方文档并且得到了很好的解释。大多数其他答案就像关掉火警警报一样! (2认同)
  • 您可能会收到“局部变量‘theElement’是多余的”。 (2认同)
  • *修改参数的属性不会改变该参数所引用的内容。*,我认为对象是通过引用传递的!请您详细说明一下好吗? (2认同)

Gya*_*eep 20

您可以在.eslintrc文件中覆盖此规则,并为此类的param属性禁用它

{
    "rules": {
        "no-param-reassign": [2, { 
            "props": false
        }]
    },
    "extends": "eslint-config-airbnb"
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这个答案是否完全包含在已接受的答案中? (2认同)
  • @DanDascalescu 在接受的答案下面有一条评论指向这个,所以也许在某个时候对其进行了编辑以使其更全面? (2认同)

ava*_*he1 9

function (el) {
  el.setAttribute('expando', {});
}
Run Code Online (Sandbox Code Playgroud)

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


Jus*_*ijn 6

这个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
});
Run Code Online (Sandbox Code Playgroud)