只要对象被重新分配,ESlint为什么对我满意?无参数重新分配

时间:2018-08-30 22:01:04

标签: javascript eslint

在ESLint中,here中记载的无参数重新分配规则禁止您分配函数参数的值。

这是为了避免修改函数的arguments对象。

正确的编码方式是将参数重新分配给本地var并返回var。对于某些类型来说,这很好,但是对于传递给函数的对象而言,似乎毫无意义。

例如,让我们使用此功能;

function foo(param) {
    var copy = param; // This makes the linter happy
    copy.bar = 2;
    console.log('arg 0: ', arguments[0], 'param:', param, 'copy:', copy);
    return copy; // A pointless return, the original object has been modified.
}

let test = { bar: 1 };
foo(test); 
console.log(test); // Has been modified
test = foo(test); // a pointless reassignment, foo has already changed test.
console.log(test); // Same effect as previous function call.

为了公平起见,ESLint 确实允许您使用/*eslint no-param-reassign: ["error", { "props": false }]*/关闭此功能;但我想知道为什么

此规则的要点是摆脱可变性并保持arguments对象纯净,但是简单地重新分配对象将无法做到这一点。

真正做到这一点的唯一方法是深度克隆参数并将其分配给函数作用域变量。

我在这里想念东西吗?

2 个答案:

答案 0 :(得分:2)

将参数分配给变量时不发出警告的可能原因是,它需要复杂的数据流分析。假设您有这样的代码:

function foo(param, flag) {
    var copy = flag ? param : {...param};
    copy.bar = 2;
    console.log('arg 0: ', arguments[0], 'param:', param, 'copy:', copy);
    return copy; // A pointless return, the original object has been modified.
}

现在,它无法确定copy是否包含与param相同的对象或克隆对象,它取决于flag的值。

或者类似这样的东西:

function foo(param) {
    var copy = param;
    var copy2 = copy;
    var copy3 = copy2;
    copy3.bar = 2;
    console.log('arg 0: ', arguments[0], 'param:', param, 'copy:', copy3);
    return copy3;
}

这将需要跟踪整个引用链,以确定copy3param相同。

跟踪它并非不可能,优化编译器通常可以做到这一点。但这对短毛猫来说可能是过大的杀伤力。

答案 1 :(得分:1)

Barmar 的回答非常中肯。我仍然在这里添加我的两分钱,因为当涉及到大型代码库时,这条规则非常重要。仅从您的示例开始,ESLint 的工作是指出错误的编码实践。作为开发人员,我们仍然可以在很多方面欺骗 linter!

在函数 # Check for abort if self.acse.is_aborted(): msg = "Association Aborted" if self.acse.is_aborted('a-p-abort'): msg += " (A-P-ABORT)" LOGGER.info(msg) self.is_aborted = True self.is_established = False evt.trigger(self, evt.EVT_ABORTED, {}) self.kill() return 中解决此 ESLint 错误的正确方法是这样 -

foo

如您所见,不需要对参数进行深度克隆。

关于您关于这条规则的原因的问题,请查看在 Github 上运行的这个超长线程,讨论与您提到的问题完全相同的问题 - https://github.com/airbnb/javascript/issues/719。希望它可以帮助您学习新的有趣的东西:)

旁注 - 简单地重新分配参数也会使代码难以遵循。这似乎也是一个坏主意,因为它在许多引擎中进行了优化,特别是 v8。老实说,我仍在阅读更多内容以更好地理解最后一行。如果您也想阅读此内容,请参阅此处 - https://github.com/airbnb/javascript/issues/641#issuecomment-167827978