在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
对象纯净,但是对象的简单重新分配将不会这样做。
真正做到这一点的唯一方法是深度克隆参数并将其分配给函数范围的变量。
我在这里错过了什么吗?
将参数分配给变量时,它不会发出警告的可能原因是它需要复杂的数据流分析。假设你有这样的代码:
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;
}
这需要跟踪整个参考链,以确定copy3
与param
相同。
跟踪这不是不可能的,优化编译器通常会这样做。但对于一个短绒来说可能有点过分。