The ...rest,spread Operator

The ... operator can be applied to an iterable in addition to an object and function parameters. When used at the left of an iterable, it expands the iterable into its elements.


var s = new Set([1, 2, 3]); // any iterable will do
var a = [0, ...s, 4, 5]; // [0, 1, 2, 3, 4, 5] spread
var [x, y, z] = a;
var [x, y, ...rest] = a; // rest
console.log(x, y, z, rest);

var arr = [1, 2, 3], first, last;
[x, ...y] = arr; // rest operator
console.log(y);
[first, ...[arr[2], last]] = arr; // spread operator
console.log(first);
console.log(last);
console.log(arr);
console.log(...arr);
console.log(Math.max(...arr));

0 1 2 [2, 3, 4, 5] [2, 3] 1 3 [1, 2, 2] 1 2 2 2

const arr = [
  {
    id: 'id1',
    level: 'l1',
    children: []
  },
  {
    id: 'id2',
    level: 'l1',
    children: [
      {
        id: 'id3',
        level: 'l2',
        children: [
          {
            id: 'id4',
            level: 'l3',
            children: []
          }
        ]
      },
      {
        id: 'id5',
        level: 'l2',
        children: []
      }
    ]
  }
];

const flatten = ({ children, ...o }) => [o, ...children.flatMap(flatten)];
console.log(arr.flatMap(flatten));

function flatten2(ar) {
  for (var i = 0; i < ar.length; i++) {
    if (ar[i].children.length)
      ar.push(...ar[i].children);
    delete ar[i].children;
  }
  return ar;
}
console.log(flatten2(arr));

[{id: "id1", level: "l1"}, {id: "id2", level: "l1"}, {id: "id3", level: "l2"}, {id: "id4", level: "l3"}, {id: "id5", level: "l2"}] [{id: "id1", level: "l1"}, {id: "id2", level: "l1"}, {id: "id3", level: "l2"}, {id: "id5", level: "l2"}, {id: "id4", level: "l3"}]

When applied to an object/array in the L.H.S, ... is called the rest operator, assigning the rest of the values to the variable. When applied to an object/array in the R.H.S., ... is called the rest operator, spreading out the packed values.