【问题标题】:How to handle eslint no-param-reassign rule in Array.prototype.reduce() functions如何在 Array.prototype.reduce() 函数中处理 eslint no-param-reassign 规则
【发布时间】:2017-05-28 06:45:43
【问题描述】:

我最近添加了 eslint 规则no-param-reassign

但是,当我使用reduce 构建一个对象(initialValue 为空对象)时,我发现自己需要在每次回调迭代时修改accumulator(回调函数的第一个参数),这会导致no-param-reassign linter 投诉(正如人们所期望的那样)。

const newObject = ['a', 'b', 'c'].reduce((result, item, index) => {
  result[item] = index; // <-- causes the no-param-reassign complaint
  return result;
}, {});

有没有更好的方法来使用reduce 构建一个不修改accumulator 参数的对象?

或者我应该在我的 reduce 回调函数中简单地禁用该行的 linting 规则?

【问题讨论】:

  • 注意,这特别是因为您已将"props": true 传递给规则。默认情况下,它不会抱怨这一点。如果您不想要这种行为,似乎将其设置为 false 是您想要的吗?或者用// eslint-disable-line no-param-reassign.标记它
  • 这是一个很好的观点@loganfsmyth。我会做一些重新检查,看看将“props”设置为 true 是否真的是我们想要的......

标签: javascript ecmascript-6 eslint


【解决方案1】:

一种解决方案是利用object spread operator

const newObject = ['a', 'b', 'c'].reduce((result, item, index) => ({
  ...result,
  [item]: index, 
}), {});

性能警告!!这是应该避免的non-performant (O(n^2) solution

【讨论】:

  • 这真的是一个好的解决方案吗?减少包含许多元素的数组,比如 2000,将创建尽可能多的新对象实例,在本例中为 2000。
  • @Amida 是的,这是非常不高效的解决方案 - 因为您可能拥有非常大的数组。而不是只使用新的(单个)对象,而是每次迭代都创建新对象,这非常慢。
  • 正如其他人之前所说,这不是高性能的。您应该只禁用该行中的 lint 规则。也许请 eslint 的人考虑为 Array.reduce 添加一个例外
【解决方案2】:

我只是将 reduce 函数包装在一个 lint 规则禁用块中,即:

/* eslint-disable no-param-reassign */
const newObject = ['a', 'b', 'c'].reduce((result, item, index) => {
  result[item] = index;
  return result;
}, {});
/* eslint-enable no-param-reassign */

【讨论】:

  • 出于性能原因,这应该是正确的答案。我相信这是最佳解决方案。 No-param-reassign 是一种防止我们在作用域之外引发副作用的方法,但是 Array.reduce 的情况是副作用问题的一个例外,因为它在内部是纯的。
【解决方案3】:

好吧,您可以使用(result, item) =&gt; Object.assign({}, result, {[item]: whatever}) 在每次迭代时创建一个新对象 :-)

如果你想欺骗 linter,你可以使用 =&gt; Object.assign(result, {[item]: whatever})(它和你当前的代码一样,但没有明确的分配),但是我想你应该简单地禁用该规则。

【讨论】:

  • 是的,我就是这么想的。也许禁用该行的规则是最好的选择...
【解决方案4】:

每当我使用Array.prototype.reduce 时,我总是将“累加器”参数命名为accu。这个约定方便我设置我的 eslint 规则:

    "no-param-reassign": [
      "error",
      {
        "props": true,
        "ignorePropertyModificationsFor": ["accu"]
      }
    ],

如果你对此参数有自己的命名约定,请将上面规则中的“accu”替换为你使用的任何内容,eslint 不会抱怨修改你的累加器。

【讨论】:

    猜你喜欢
    • 2021-01-09
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 2016-01-08
    相关资源
    最近更新 更多