So... ES6¹ (which happens to be standardized a few hours ago) brings default parameters for functions similar to those in PHP, Python etc. I can do stuff like:
function foo (bar = 'dum') {
return bar;
}
foo(1); // 1
foo(); // 'dum'
foo(undefined); // 'dum'
MDN says that the default value for the parameter is evaluated at call time. Which means each time I call the function, the expression 'dum'
is evaluated again (unless the implementation does some weird optimizations which we don't care about).
My question is, how does this
play into this?
let x = {
foo (bar = this.foo) {
return bar;
}
}
let y = {
z: x.foo
}
x.foo() === y.z(); // what?
The babel transpiler currently evaluates² it as false
, but I don't get it. If they are really evaluated at call time, what about this:
let x = 'x from global';
function bar (thing = x) {
return thing;
}
function foo () {
let x = 'x from foo';
return bar();
}
bar() === foo(); // what?
The babel transpiler currently evaluates³ it as true
, but I don't get it. Why does bar
not take the x
from foo
when called inside foo
?
Yes, the parameter initializers are evaluated at call time. It's complicated, but the steps are basically as follows:
with a new environment in the "closure scope" of the called function
thisBinding
is initialisedarguments
object is created an boundIn the course of this, initialisers are evaluated
undefined
let
andconst
variables in the function body are createdSo parameter initialisers do have access to the
this
and thearguments
of the call, to previously initialised other parameters, and everything that is in their "upper" lexical scope. They are not affected by the variables declared in the function body (though they are affected by all the other parameters, even if in their temporal dead zone).Because
x
is a local variable thatbar
does not have access to. We're so lucky that they are not dynamically scoped! The parameter initialisers are not evaluated at the call site, but inside the called function's scope. In this case, thex
identifier is resolved to the globalx
variable.