I find ESLint very helpful when coding in Javascript, but I wonder why there is no rule that checks for the correct number of parameters in a function call:
function myFunction(param1) {
}
...
myFunction(param1,param2);
does not get detected, though it totally violates a reasonable rule. Do I miss something?
Someone could write such a rule, but there are two issues:
It's impossible to use static analysis to determine what function is being called in all cases, so for foo(1)
, ESLint may or may not be able to tell what function foo
refers to. So such a rule would at best be unreliable. Consider:
function a() {
return 42;
}
function b(x) {
return x * 2;
}
var f = Math.random() < 0.5 ? a : b;
f();
Should ESLint complain? How can it know whether a
or b
is being called?
So such a rule is unenforceable without introducing a type system allowing us to associate types with variables/properties that refer to functions. JavaScript, of course, doesn't have typed variables/properties. (If you want type-safety of that sort, you can use TypeScript, which allows for applying types to functions.)
It's perfectly valid in JavaScript to call a function with fewer or more arguments than it has formal parameters. Some functions are designed to be called that way. You'd need a way to tell ESLint that that was your intention (and again: ESLint may not know what function is being called).
Re #2, in ES5 and earlier, we'd write a "varargs" (variable arguments) function using arguments
and/or checking for undefined
as the value of a formal parameter:
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);
So while it would be possible to write an ESLint tool that compared calls to a function with the number of formal parameters it declares, the rule would constantly be running up against exceptions.
But now that ES2015 introduced both rest arguments and parameter defaults, someone may well write such a rule, as the combination of rest arguments and parameter defaults makes it much more likely we can express our parameter expectations clearly in our function declarations. Here's that same function with ES2015 features:
function foo(formal = "default", ...rest) {
// Show our formal parameter
console.log("formal =", formal);
// Show any additional varargs we may handle
for (const arg of rest) {
console.log("additional =", arg);
}
}
foo();
foo(1, 2, 3);
Note how the declaration would indeed allow ESLint to enforce a rule. But again, see #1: ESLint cannot know from static analysis what function is being called, reliably.
that is reasonable but not necessary because in js
function f(a){
console.log(arguments.length);//3
}
f(1,2,3);
you can get the other auguments by arguments[1],arguments[2]
in es6,we can get all arguments by ...
function f(...args){
console.log(args.length);
}
however,we can't do this in es5 or es3.when that happens,the arguments worked because some function can accept a lot of arguments and can't be sure of the number of arguments.
for example,push(),concat()
actually if you send more arguments than needed,normally,the function just ignore that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With