我发现 ESLint 在用 Javascript 编码时非常有用,但我想知道为什么没有规则来检查函数调用中参数的正确数量:
function myFunction(param1) {
}
...
myFunction(param1,param2);
Run Code Online (Sandbox Code Playgroud)
不会被发现,尽管它完全违反了合理的规则。我错过了什么吗?
有人可以写这样的规则,但有两个问题:
不可能使用静态分析来确定在所有情况下都调用了哪个函数,因此对于foo(1),ESLint 可能会也可能无法分辨出哪个函数foo引用。因此,这样的规则充其量是不可靠的。考虑:
function a() {
return 42;
}
function b(x) {
return x * 2;
}
var f = Math.random() < 0.5 ? a : b;
f();
Run Code Online (Sandbox Code Playgroud)
ESLint 应该抱怨吗?它如何知道是否a或b正在被调用?
因此,如果不引入允许我们将类型与引用函数的变量/属性相关联的类型系统,这样的规则是无法执行的。当然,JavaScript 没有类型化的变量/属性。(如果你想要那种类型安全,你可以使用 TypeScript,它允许将类型应用于函数。)
在 JavaScript 中调用参数比形式参数少或多的函数是完全有效的。某些函数被设计为以这种方式调用。您需要一种方法来告诉 ESLint 那是您的意图(再说一次:ESLint 可能不知道正在调用什么函数)。
#2,在 ES5 及更早版本中,我们会编写一个“varargs”(可变参数)函数,使用arguments和/或检查undefined作为形式参数的值:
function a() {
return 42;
}
function b(x) {
return x * 2;
}
var f = Math.random() < 0.5 ? a : b;
f();
Run Code Online (Sandbox Code Playgroud)
因此,虽然可以编写一个 ESLint 工具,将函数调用与其声明的形式参数数量进行比较,但该规则将不断遇到异常。
但是现在 ES2015 引入了剩余参数和参数默认值,有人可能会编写这样的规则,因为剩余参数和参数默认值的组合使我们更有可能在函数声明中清楚地表达我们的参数期望。这是具有 ES2015 特性的相同功能:
function foo(formal) {
// Supply a default for our formal parameter
if (formal === undefined) { // or you might see `if (arguments.length === 0)` here
formal = "default";
}
console.log("formal =", formal);
// Show any additional varargs we may handle
for (var i = 1; i < arguments.length; ++i) {
console.log("additional =", arguments[i]);
}
}
foo();
foo(1, 2, 3);Run Code Online (Sandbox Code Playgroud)
请注意声明如何确实允许 ESLint 强制执行规则。但同样,请参见 #1:ESLint 无法从静态分析中可靠地知道正在调用什么函数。