fail-fast object destructuring
Brendan Eich
brendan at mozilla.org
Mon Jun 25 09:14:22 PDT 2012
Andreas Rossberg wrote:
> On 25 June 2012 17:17, David Herman<dherman at mozilla.com> wrote:
>> Implicit coercions suck, and IMO it would be better if destructuring didn't add new ones to JS. In the current draft spec, I believe if you match an object destructuring pattern against a non-object or an object that doesn't have one or more of the properties, it quietly proceeds -- masking what is quite likely an error:
>>
>> var { foo, bar } = getFooAndBar();
>>
>> If getFooAndBar() doesn't produce an object with foo and bar properties, there's probably something going wrong! And most of the time when you do want to be forgiving (say, in a function signature, or when reading a configuration file), you have a specific default value you want to provide, which can be specified with the default syntax:
>>
>> var { foo = defaultFooValue, bar = defaultBarValue } = getFooAndBar();
>>
>> I'd like to propose the following changes:
>>
>> (a) Throw when matching null, undefined, booleans, or strings against an object pattern. (I don't propose throwing when matching a string against an array pattern, however, since strings behave structurally like read-only arrays.)
>>
>> (b) Allow a shorthand "?" prefix for properties in an object destructuring pattern. This is simply shorthand for defaulting to undefined. IOW, the following are all equivalent:
>>
>> var { ?foo } = getFoo();
>> var { foo = undefined } = getFoo();
>> var { foo: foo = undefined } = getFoo();
>> var { ?foo: foo } = getFoo();
>>
>> Note, however, that (b) is not strictly necessary to get the fail-soft behavior. You can always write the explicit default. But it makes it considerably more convenient to get the fail-soft behavior when you want it -- only one character more expensive than fail-fast.
>
> +10^20, although you don't say that "let {foo} = {}" should throw as
> well -- but your (b) doesn't seem to be motivated without proposing
> that.
Dave did write "If getFooAndBar() doesn't produce an object with foo and
bar properties, there's probably something going wrong!"
The test would be "in" not "own", to be clear, so if
Object.prototype.foo = 42 had been done previously, let {foo} = {} would
destructure 42 as the initial value of the foo let binding.
I'm ok with this even though it is not compatible with what we've
implemented and user-tested for almost six years, but I want (b) as part
of the deal. We have code that will use ?-prefixing.
/be
More information about the es-discuss
mailing list