【问题标题】:How to avoid "Assignment to property of function parameter 'elem'" eslint rule?如何避免“分配给函数参数'elem'的属性”eslint规则?
【发布时间】:2018-05-20 12:26:18
【问题描述】:

我想了解你们如何避免eslint warning "Assignment to property of function parameter 'elem'"。我知道这是一个很好的模式,不要更改函数参数值。这使我们的代码保持解耦并具有高维护性。但是,在某些情况下,我遇到了以下情况。 我需要检索具有特定类的所有元素,然后更改其显示样式属性。 这是我的代码:

const setDisplayStyleToElementsArray = (arr, display) => {
  arr.map((elem) => {
    elem.style.display = display;
    return elem;
  });
};

const elements = document.getElementsByClassName('.myClass');

const myFields = [].slice.call(elements, 0);

setDisplayStyleToElementsArray(myFields, 'block');

在这种情况下,我将更改所有 .myClass 元素的属性“块”。如何做到这一点没有副作用?这样做的正确方法是什么? 提前致谢

【问题讨论】:

  • 更干净的方式:let myFields = [... elements]
  • 只是一个观察:使用forEach 而不是map(因为您没有使用返回的数组)。
  • 很想知道您为什么使用.map(),但忽略了它正在创建的新数组。这是尝试解决 ESLint 警告吗?
  • Eslint 默认设置属性/*eslint no-param-reassign: ["error", { "props": false }]*/。但不是airbnb风格指南。 @rockstar
  • 这是展开操作符对集合进行迭代的方式。其他选项是Array.from(elements),它也比 ES5 方式更干净。

标签: javascript eslint eslint-config-airbnb


【解决方案1】:

我正在更改属性。如何做到这一点没有副作用?

你不能。更改 DOM 属性的副作用。如果您的 linter 阻止您这样做,请禁用它(至少在该行上)。

当然,可以通过不使用map 或回调函数来避免此特定规则。更惯用的是

function setDisplayStyles(arr, display) {
  for (const elem of arr) {
    elem.style.display = display;
  }
}

const elements = Array.from(document.getElementsByClassName('.myClass'));
setDisplayStyles(elements, 'block');

【讨论】:

  • 我想知道为什么这会有助于避免这条规则。 arr 参数仍在变异中。
  • @rockstar 我认为 ESLint 不够聪明,无法弄清楚 elemarr 之间的关系。在原始代码中,elem 本身就是一个函数参数。
  • forEach() 对 OPs 原始代码的改动很小
  • 现在我得到了上面 OP 评论的错误,for-of 确实修复了它,所以你是对的,他们只是没有一直遵循参考。我也通过取原件确认了这一点,分配var el = elem;,然后对el进行操作,也避免了错误。
  • @PabloDarde 识别和警告反模式是 linter 的工作,而不是转译器。
【解决方案2】:

首先,感谢所有cmets,感谢。在与我的同事以及在网络上对这个问题进行了一些研究之后,我遇到了一个 Lecture by Douglas Crockford 谈论这个问题。尽管上面的答案似乎简单而优雅,但它似乎并不是最具表现力的恕我直言。所以,如果有人对此有更好的意见,请告诉我。

基本上,我决定使用Object.keys(htmlCollection).forEach(...) 而不是for,同意Douglas Crockford 的想法。这样一来,codeclimate 就不会发出任何警告,而且我的代码似乎更符合逻辑和流畅。

const setDisplayStyleToElementsArray = (arr, display) => {
	Object.keys(arr).forEach(field => arr[field].classList.add('hidden'));
};

const elements = [... document.getElementsByClassName('myClass')];
setDisplayStyleToElementsArray(elements, 'none');
.myClass {
  border: 1px solid red;
}

.hidden {
  border: 1px solid blue; //could be display: none;
}
<div class="myClass">One</div>
<div class="myClass">Two</div>

【讨论】:

    猜你喜欢
    • 2019-11-09
    • 2020-05-10
    • 2021-12-27
    • 1970-01-01
    • 2019-07-29
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多