2

I am reading info about array destructuring and the spread syntax from MDN and I have stumbled upon the following example that left me a bit cold, despite going over the material progressively.

The code giving me trouble is this:

function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);

I get that v==-1; w==0; x==1; and y==2... but what is ...[3]?

The example is from the spread syntax hyperlink above.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
alexandros84
  • 321
  • 4
  • 14
  • 1
    It's just an array literal. Think `var args2 = [3];` and `...args2`. – Bergi Jun 19 '17 at 23:18
  • thanks I panicked and posted question a bit prematurely. One positive thing is that I learned that you can copy arrays without slice that way: var arr = [1,2,3]; var arr2 = [...arr]; // like arr.slice() – alexandros84 Jun 19 '17 at 23:27
  • 2
    [`...` is not an operator!](https://stackoverflow.com/questions/37151966/what-is-spreadelement-in-ecmascript-documentation-is-it-the-same-as-spread-oper/37152508#37152508) – Felix Kling Jun 20 '17 at 00:16
  • @FelixKling first of all ty for ur contributions to the community. many of us dont have a cs background and is amazing to have someone with ur willingness to share top-notch knowledge :) So u would describe it as an element? (because it clearly seems to conduct an operation). – alexandros84 Jun 20 '17 at 00:57
  • 1
    `...` doesn't really have a name. It's a punctuator that is only meaningful in context. Take `;` for example. It's meaning is different in `for( ; ; ) {}` and `var x=42;`. Same with `...`, although the different occurrences are closer related. In your example, since the context is a function *call* you can refer to `...arg` as a *spread argument*. It's not an operator because an operator produces a single value and can be embedded into other expression. However you cannot do `42 + ...someValue`. – Felix Kling Jun 20 '17 at 01:20

1 Answers1

3

The example you've found is a bit contrived, and you probably wouldn't see it in real code. It's just meant to illustrate that the spread argument syntax ... works with any iterable expression, including standard array literals like [1, 2, 3]. z will be 3 because

myFunction(-1, ...args, 2, ...[3]);

is equivalent to

myFunction(-1, ...args, 2, 3);

The ...[ and ] essentially have no effect in this case; the values are pulled out of the array so it's as though you'd just written them directly in the argument list. As another example,

myFunction(-1, ...args, 2, ...[3, 4, 5]);

is equivalent to

myFunction(-1, ...args, 2, 3, 4, 5);

although z would still be 3 (4 and 5 would be ignored because they're unexpected extra arguments).

Let's break this down a bit: the behaviour of the spread/rest syntax ... in an argument list is defined in section 12.3.6.1 "Runtime Semantics: ArgumentListEvaluation" of ECMAScript 6. To paraphrase, it essentially says "when you see ...X in an argument list, evaluate X, then go through the values it contains and add each of them as a separate argument".

So, when JavaScript sees , 3 in an argument list, it says "add 3 to the argument list".

But when JavaScript sees , ...[3] in an argument list, it says "create a new array containing 3, then go through each of its values (only 3) and add them to the argument list".

You're doing the same thing in both cases, but the simpler way is probably faster.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • Certainly weird thing to have in an example without a single comment. Much improved answer. I hope you understand that I cannot upvote an answer that does not upvote the question.. and that it will take me some time to accept your answer (until I understand what is going on myself). Ty. – alexandros84 Jun 19 '17 at 23:09
  • So is it like spreading [3] in its contents, that is 3 itself? So if it was ...[3,4]; it would be 3,4? – alexandros84 Jun 19 '17 at 23:15
  • @alexandros84 Yes, that's right, and that is a good further example to add to my answer. Yes, it's as though the `...[` and `]` aren't there; any values you put inside the brackets will be treated as arguments the same as if they were outside. – Jeremy Jun 19 '17 at 23:17
  • Oh man I get it now... I panicked and posted a question prematurely. Blame my confusion to the rest operator I was reading about earlier... – alexandros84 Jun 19 '17 at 23:18
  • This is a great way indeed to copy arrays, var arr = [1,2,3]; var arr2 = [...arr]; // like arr.slice() – alexandros84 Jun 19 '17 at 23:22
  • [`...` is not an operator!](https://stackoverflow.com/questions/37151966/what-is-spreadelement-in-ecmascript-documentation-is-it-the-same-as-spread-oper/37152508#37152508) – Felix Kling Jun 20 '17 at 00:16
  • @FelixKling Thank you for the correction; updated answer. – Jeremy Jun 20 '17 at 00:25