Default function arguments not using current scope
On Thu, Apr 5, 2018 at 9:29 AM, Cyril Auburtin <cyril.auburtin at gmail.com> wrote:
I don't understand:
var z=1; var fn = (z = z) => z; fn() // throws ReferenceError: z is not defined
SpiderMonkey's error message is a bit clearer here:
ReferenceError: can't access lexical declaration `z' before initialization
Remember that default parameter values have their own scope. In that scope,
they have a TDZ (like let
and const
do in a block) until they're
initialized. I believe this is covered in
FunctionDeclarationInstantiation Step 28. At the point the default
value expression = z
is evaluated, the z
parameter has been created as
an uniniitialized binding (by CreateMutableBinding in 28.f.i.2).
Consequently, it tries to get the value of that uninitialized binding,
which results in a ReferenceError as described in Table 14 under
Environment Records:
GetBindingValue(N, S) - Returns the value of an already existing
binding from an Environment Record. The String value N is the text of the bound name. S is used to identify references originating in strict mode code or that otherwise require strict mode reference semantics. If S is true and the binding does not exist throw a ReferenceError exception. If the binding exists but is uninitialized a ReferenceError is thrown, regardless of the value of S.
(My emphasis.)
E.g., you get that error for the reason you get that same error from:
var z = 42; { console.log(z); let z; }
-- T.J. Crowder
Thanks for the clear explanation
2018-04-05 11:08 GMT+02:00 T.J. Crowder <tj.crowder at farsightsoftware.com>:
I don't understand:
var z=1; var fn = (z = z) => z; fn() // throws ReferenceError: z is not defined