Allen Wirfs-Brock (2014-05-31T20:54:29.000Z)
On May 31, 2014, at 8:59 PM, Nicholas C. Zakas <standards at nczconsulting.com> wrote:

> I've been playing around with using destructuring as function arguments and have come across some odd behaviors that I'm not sure are intentional (or perhaps, not to spec).

Argument binding initialization takes place as part of http://people.mozilla.org/~jorendorff/es6-draft.html#sec-functiondeclarationinstantiation 
The actual initialization takes place in steps 24-25, essentially treating the entire parameter list as an array-like restructuring

Note that there has been significant tweaks to this section in each of the 3 latest spec. drafts.  You favorite implementation may not match the current spec. text.

> For context, consider the following function:
> 
> ```
> function setCookie(name, value, { secure, path, domain, expires }) {
>    console.log(secure);
>    // ...
> }
> 
> // called as
> setCookie("type", "js", {
>    secure: true
> });
> ```
> 
> What happens here:
> * `secure === true`
> * `path === undefined`
> * `domain === undefined`
> * `expires === undefined`
> 
> I'd say all of that behavior is as expected. However, if I omit the third argument completely, things get a bit strange:
> 
> ```
> setCookie("type", "js");   // throws error at console.log
> ```
> 
correct, this should throw a TypeError exception because desctructuring patterns (in any context) require an object value to restructure.  Since you did not pass a third argument there is no object to restructure into {secure, path, domain, expires}


> What happens here is that none of `secure`, `path`, `domain`, `expires` are defined. I can use `typeof` on them to protect against this, but then I end up with some lousy looking code:

not really, the thrown exception while processing the arguments should terminate the function and you should never start executing the function body 
> 
> ```
> function setCookie(name, value, { secure, path, domain, expires }) {
> 
>    if (typeof secure !== "undefined") {
>        // use it
>    }
> 
>    if (typeof path !== "undefined") {
>        // use it
>    }
> 
>    if (typeof domain !== "undefined") {
>        // use it
>    }
> 
>    if (typeof expires !== "undefined") {
>        // use it
>    }
> 
>    // ...
> }
> ```
> 
> My first thought was that this behavior made sense, since no destructuring can happen on undefined. However, the workaround for dealing with that behavior seems a bit heavy-handed.
> 
> I thought perhaps I could assign a default value, and that would solve the problem:
> 
> ```
> function setCookie(name, value, { secure, path, domain, expires } = {}) {
>    console.log(secure);
>    // …

yes the above is exactly what you are expected to do.  Or you could include some defaults in the default object:

{secure, path, domain, expires } = {secure: false}



> }

> ```
> 
> Unfortunately, that resulted in a syntax error in Firefox. Traceur seems to have no problem with it.

that sounds like a Firefox bug
> 
> So I really have two questions:
> 
> 1. Who is right about assigning a default value to a destructured parameter, Firefox or Traceur?

Traceur
> 2. Is the behavior of not having any bindings for destructured parameter properties correct? And if so, is it desirable?

no, it is supposed to throw as discussed above.

Allen




> 
> Thanks.
> 
> -- 
> ___________________________
> Nicholas C. Zakas
> http://www.nczonline.net
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140531/a75248a0/attachment-0001.html>
domenic at domenicdenicola.com (2014-06-10T19:00:21.674Z)
On May 31, 2014, at 8:59 PM, Nicholas C. Zakas <standards at nczconsulting.com> wrote:

> I've been playing around with using destructuring as function arguments and have come across some odd behaviors that I'm not sure are intentional (or perhaps, not to spec).

Argument binding initialization takes place as part of http://people.mozilla.org/~jorendorff/es6-draft.html#sec-functiondeclarationinstantiation 
The actual initialization takes place in steps 24-25, essentially treating the entire parameter list as an array-like restructuring

Note that there has been significant tweaks to this section in each of the 3 latest spec. drafts.  You favorite implementation may not match the current spec. text.

> For context, consider the following function:
> 
> ```
> function setCookie(name, value, { secure, path, domain, expires }) {
>    console.log(secure);
>    // ...
> }
> 
> // called as
> setCookie("type", "js", {
>    secure: true
> });
> ```
> 
> What happens here:
> * `secure === true`
> * `path === undefined`
> * `domain === undefined`
> * `expires === undefined`
> 
> I'd say all of that behavior is as expected. However, if I omit the third argument completely, things get a bit strange:
> 
> ```
> setCookie("type", "js");   // throws error at console.log
> ```
> 

correct, this should throw a TypeError exception because desctructuring patterns (in any context) require an object value to restructure.  Since you did not pass a third argument there is no object to restructure into {secure, path, domain, expires}


> What happens here is that none of `secure`, `path`, `domain`, `expires` are defined. I can use `typeof` on them to protect against this, but then I end up with some lousy looking code:

not really, the thrown exception while processing the arguments should terminate the function and you should never start executing the function body 
> 
> ```
> function setCookie(name, value, { secure, path, domain, expires }) {
> 
>    if (typeof secure !== "undefined") {
>        // use it
>    }
> 
>    if (typeof path !== "undefined") {
>        // use it
>    }
> 
>    if (typeof domain !== "undefined") {
>        // use it
>    }
> 
>    if (typeof expires !== "undefined") {
>        // use it
>    }
> 
>    // ...
> }
> ```
> 
> My first thought was that this behavior made sense, since no destructuring can happen on undefined. However, the workaround for dealing with that behavior seems a bit heavy-handed.
> 
> I thought perhaps I could assign a default value, and that would solve the problem:
> 
> ```
> function setCookie(name, value, { secure, path, domain, expires } = {}) {
>    console.log(secure);
>    // …
> ```

yes the above is exactly what you are expected to do.  Or you could include some defaults in the default object:

```js
{secure, path, domain, expires } = {secure: false}
```

> ```js
> }
> ```
> 
> Unfortunately, that resulted in a syntax error in Firefox. Traceur seems to have no problem with it.

that sounds like a Firefox bug
> 
> So I really have two questions:
> 
> 1. Who is right about assigning a default value to a destructured parameter, Firefox or Traceur?

Traceur

> 2. Is the behavior of not having any bindings for destructured parameter properties correct? And if so, is it desirable?

no, it is supposed to throw as discussed above.