What does `hasParameterExpressions` have to do with `argumentsObjectNeeded`?

Step 18 of FunctionDeclarationInstantiation:

  1. Else if hasParameterExpressions is false, then
    a. If "arguments" is an element of functionNames or if "arguments" is an element of lexicalNames, then
       i. Set argumentsObjectNeeded to false.

Why is 18.a. conditional on hasParameterExpressions being false? Shouldn't argumentsObjectNeeded be set to false if 18.a. is true, regardless of the value of hasParameterExpressions?

Short version: you can observe the arguments object by having an expression in the parameter list, even if you couldn't otherwise observe it in the body.


Long version: it's relevant because if there is a variable named arguments declared at the top level of the body of the function - i.e., in the functionNames or lexicalNames, as in function f(){ let arguments; } - then that would shadow arguments everywhere in the body of the function, but would not shadow it in parameters. That is, in

function f() {
  // anything
  let arguments;
  // anything
}

it is impossible to observe the arguments object no matter what statements you put in the anything positions (so you don't need the arguments object), but

function f(x = console.log(arguments)) {
  // anything
  let arguments;
  // anything
}

observes the actual arguments object when calling f() (so you do need the arguments object).

1 Like

Thank you @bakkot!

Sorry to bother you @bakkot, but I have a follow up question regarding 18.a: why is argumentsObjectNeeded assigned false if there's already a function declaration named "arguments"?

I understand that argumentsObjectNeeded must be set to false if there exists a lexical declaration named "arguments" so as to prevent a redeclaration error, but I'm not sure why the same is done for function declarations, since they are redeclarable.

I believe the purpose is to point out to implementations that they can avoid creating the arguments object in some cases, as an optimization.

The spec doesn't usually do that kind of thing, but for some reason there are several such optimizations in this method. E.g. step 19 is not actually observable to user code, and is there just to point out to engines that a particular optimization is possible.

1 Like

That makes sense, thank you for getting back so quickly.