The grammar for a setter in an object literal is:
> MethodDefinition [Yield] :
> ...
> set PropertyName ( PropertySetParameterList ) { FunctionBody }
And we have
> PropertySetParameterList :
> FormalParameter
and then
> FormalParameter [Yield,GeneratorParameter] :
> BindingElement [?Yield, ?GeneratorParameter]
and then
> BindingElement [Yield, GeneratorParameter ] :
> SingleNameBinding [?Yield, ?GeneratorParameter]
> [+GeneratorParameter] BindingPattern [?Yield,GeneratorParameter] Initializer [In]opt
> [~GeneratorParameter] BindingPattern [?Yield] Initializer [In, ?Yield]opt
and
> SingleNameBinding [Yield,GeneratorParameter] :
> [+GeneratorParameter] BindingIdentifier [Yield] Initializer [In]opt
> [~GeneratorParameter] BindingIdentifier [?Yield] Initializer [In, ?Yield]opt
Every expansion of BindingElement permits an initializer. But setter method syntax is unique and unusual in that it is specifically tailored to setters, in that exactly one argument must be present. No provision is made for the setter being a general function taking any number of arguments other than 1. Given that precedent and the ongoing existence of PropertySetParameterList, it seems strange that top-level initializers are permitted here.
Instead of the current grammar, I think we should instead have
PropertySetFormalParameter :
BindingIdentifier
BindingPattern
to restrict this argument to a name or a destructuring pattern *without* an initializer. (Note that nested initializers would still be fine with this, as in the following example -- this just prohibits an initializer for the single argument passed to the setter.)
var API =
{
_count: 0,
_rational: true,
set options({ count = 17, rational = true }) {
this._count = count;
this._rational = rational;
}
};
API.options = { count: 25 }; // would imply rational = true
But, default parameter value initializes are also trigger by passing the value undefined. So you might reasonably say:
var o={set foo(value=null) {doSomething(value)}};
o.value = undefined; //null gets passed to doSomething
It since use cases like this are possible, it seems reasonable to not try to special case away the initializer. Even though it will be very infrequently used. Fewer special cases is better.
Oh, right, I forgot that defaults aren't just for not-present arguments (a decision I don't particularly like, but whatever). Never mind then.