Javascript 在DOM对象上设置属性时如何避免不重新指定参数

Javascript 在DOM对象上设置属性时如何避免不重新指定参数,javascript,dom,eslint,Javascript,Dom,Eslint,我有一个方法,它的主要目的是在DOM对象上设置属性 function (el) { el.expando = {}; } 我使用AirBnB的代码样式,这使得ESLint抛出一个无参数重新分配错误: 分配到函数参数“el”时出错无参数重新分配 在符合AirBnB的代码样式时,如何操作作为参数传递的DOM对象 有人建议使用/*eslint react/prop类型:0*/引用,但如果我没有弄错的话,这适用于react,但不适用于本机DOM操作 我也不认为改变代码风格是一个答案。我相信使用标准

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

function (el) {
  el.expando = {};
}
我使用AirBnB的代码样式,这使得ESLint抛出一个
无参数重新分配
错误:

分配到函数参数“el”时出错无参数重新分配

在符合AirBnB的代码样式时,如何操作作为参数传递的DOM对象

有人建议使用
/*eslint react/prop类型:0*/
引用,但如果我没有弄错的话,这适用于react,但不适用于本机DOM操作

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


为了记录在案,我在GitHub上询问了AirBnB,他们认为在这些情况下应该怎么做。

正如@Mathletics所建议的,您完全可以通过将此添加到
.eslintrc.json
文件中:

"rules": {
  "no-param-reassign": 0
}
或者,您可以禁用专门用于参数属性的规则

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

您可以在
.eslintrc
文件中重写此规则,并对类似以下的参数属性禁用它

{
    "rules": {
        "no-param-reassign": [2, { 
            "props": false
        }]
    },
    "extends": "eslint-config-airbnb"
}
此方式规则仍处于活动状态,但不会对属性发出警告。 更多信息:

您可以使用:

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

那些希望有选择地停用此规则的人可能对
无参数重新分配
规则感兴趣,该规则将允许对象名称的“白名单”,对于哪些参数重新分配应被忽略。

您也可以使用lodash
assignIn
,它会改变对象。

赋值(obj,{someNewObj});

因为,这条规则是为了避免基因突变。如果分配给参数,然后尝试通过
参数
对象访问某些参数,可能会导致意外结果

您可以使用另一个变量获取对DOM元素的引用,然后修改该引用,从而保持规则的完整性并保持AirBnB样式:

function (el) {
  var theElement = el;
  theElement.expando = {};
}
在JS中,对象(包括DOM节点)是通过引用传递的,因此这里的
el
theElement
都是对同一DOM节点的引用,但是修改
theElement
不会改变
arguments
对象,因为
arguments[0]
仍然只是对该DOM元素的引用

该方法在以下文件中有所暗示:

此规则的正确代码示例:

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

您可以使用更新数据的方法。例如,“res.status(404)”而不是“res.statusCode=404” 我找到了解决办法

以下是:


no param reassign
警告对于普通函数有意义,但对于经典的
数组来说是有意义的。forEach
在您想要变异的数组上循环是不合适的

但是,为了避免这种情况,您还可以将
Array.map
与新对象一起使用(如果您和我一样,不喜欢带注释的打盹警告):


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

如果您真的不想禁用该规则,更新后的替代方案可能是:

功能(el){
Object.defineProperty(el,“expando”{
值:{},
可写:对,
对,,
可枚举:true
});
}

参考资料:

Nah。首先,这将意味着在该规则适用的所有其他情况下禁用该功能。其次,我相信你要么遵循风格指南,要么不遵循。至少如果它是一个样式指南,被各种各样的项目中的许多开发人员遵循。但是你在问如何不遵守样式指南,因为你正在做它试图阻止的事情。在任何情况下,@Mathletics的复制品都是可能的。不,我觉得这个规则很有道理,但它不适用于这个特定的情况。我想知道是否有一种方法可以按照规则进行操作。不管你怎么说,你想要的操作都与规则冲突。也就是说,这似乎是一个XY问题;我不会像那样将属性直接附加到DOM节点。谢谢。似乎大多数人都认为修改门楣是最好的方法。对我来说,将这一点应用于一行似乎是目前最好的折衷办法。这确实是有意义的,例如,对于nodejs express项目,有时您可能需要立即修改
res.session
,如果问题仅在于设置问题中所述的函数参数属性,Gyandeep下面的答案要好得多。答案中的链接不起作用Anks@hiehuehue:看起来他们把它取下来了。删除链接。这不是只修改副本吗(这有什么价值)?这不是一个真正的解决方案,因为这意味着通过创建一个新对象来避免参数重新分配,而我明确地不需要创建一个新对象,而是要修改原始对象。我不希望修改参数,但您也可以使用object.defineProperty()如果你这样做,门楣不会给你一个错误。这根本不起作用。您正在创建变量的副本,将其属性复制到新对象上,修改属性,然后不返回它,因此不会发生任何事情。即使您确实返回了它,也返回了一个对象,而不是像传入的那样返回DOM元素。最重要的是,用于从对象复制到目标对象。像这样尝试从DOM元素复制会导致一个空对象。如果您尝试使用循环引用(例如套接字连接)重新分配对象上的属性,则Plus
object.assign
将无法正常工作<代码>对象。默认情况下,分配是浅层
/*eslint no-param-reassign: "error"*/

function foo(bar) {
    var baz = bar;
}
/*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsFor": ["$scope"] }]*/

app.controller('MyCtrl', function($scope) {
  $scope.something = true;
});
function (el) {
  const element = el
  element.expando = {}
}
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', {});
}