46

I don't understand what the ... notation does exactly.

I tried a simple example with Babel to understand it (view the example), but it seems that:

ES6 syntax

let myArray = [1, 2, 3, ...18];

console.log(myArray); // [1, 2, 3]
console.log(myArray[4]);// undefined
console.log(myArray.length); // 3

is the same as this ES5 syntax:

"use strict";

function _toConsumableArray(arr) { 
    if (Array.isArray(arr)) { 
        for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
             arr2[i] = arr[i];
        }
        return arr2;
     } else { 
        return Array.from(arr); 
     } 
}

var myArray = [1, 2, 3].concat(_toConsumableArray(18));

console.log(myArray); // [1, 2, 3]
console.log(myArray[4]); // undefined
console.log(myArray.length); // 3

BUT: What does this code do? Because the output (console.log) is the same as in this code (ES5):

var myArray = [1,2,3];

console.log(myArray); // [1, 2, 3]
console.log(myArray[4]);// undefined
console.log(myArray.length); // 3

What does the ...18 notation mean?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Aral Roca
  • 5,442
  • 8
  • 47
  • 78

2 Answers2

46

The ...(spread operator) works by returning each value from index 0 to index length-1:

As example:

[...'18'] // returns ['1', '8']

which would be the same as:

['18'[0], '18'[1]]

Now, to get an array from 1 to 18, you can do this:

[...Array(19).keys()].slice(1)

Or this with map:

[...Array(18)].map(_=>i++,i=1)

Hope it helps.

  • 17
    That's quite irrelevant (in my opinion). OP wants to understand `...`, not create an array 1 to 18 – Amit Mar 18 '16 at 23:07
  • Well my goal is to understand the new (for me) ES6 syntax, not to do this, but thank you any way. Well, if I do finally this with strings `let myArray = ['1','2','3', ...'18'];` why the console log is now `["1", "2", "3", "1", "8"]` ? – Aral Roca Mar 18 '16 at 23:11
  • @AralRoca. Because `'18'` has index `0` and `1`, it will return each value in its positions as parameters –  Mar 18 '16 at 23:12
  • 2
    @AralRoca. Without the `...` (_spread operator_) it would be `['1','2','3','18'[0],'18'[1]]` –  Mar 18 '16 at 23:14
  • 3
    uoooo! Nice. Now is clear. Thank you so much! – Aral Roca Mar 18 '16 at 23:14
  • 2
    Glad to see you understood... I will update my answer with these notes –  Mar 18 '16 at 23:15
  • 1
    *"The ...(spread operator) works by returning each value from index `0` to index `length-1`"* That's not quite correct. The spread "operator" (it's not an operator) works with any **iterable** value. An iterable value is a value that has a `[Symbol.iterator]` property. – Felix Kling Mar 19 '16 at 00:05
  • I know, OP is about JavaScript, but just note: the "create array" part is not working in TypeScript: `Type 'IterableIterator' is not an array type`. – Martin Schneider Apr 25 '18 at 20:13
7

The expression [1, 2, 3, ...18] is invalid.

You cannot use ... with a Number. You can only use ... with an iterable object like an Array, String or Object.

It is interesting to note that Tracur - another transpiler - throws an error when fed the same code:

TypeError: Cannot spread non-iterable object.

I am not intimate with the specification but I think this could be a Babel "bug".

Alex Booker
  • 10,487
  • 1
  • 24
  • 34