Help us understand the problem. What is going on with this article?

スプレッド・レスト構文七変化

More than 1 year has passed since last update.

配列/オブジェクトの一部として挿入(スプレッド構文)

配列やオブジェクトにスプレッド演算子を使用すると、元のリテラルを展開しながら挿入することが可能になり、結果配列やオブジェクトの一部として同階層に配列/オブジェクトを挿入することができます。

配列を配列に入れる

a = [ 1, 2, 3 ];
b = [ 4, 5, ...a, 6 ];

console.log(b);

// -> Array(6) [ 4, 5, 1, 2, 3, 6 ]

オブジェクトをオブジェクトに入れる

a = {
  z1: 1,
  z2: 2,
  z3: 3
};
b = {
  z4: 4,
  ...a,
  z5: 5
};
console.log(b);

// -> Object { z4: 4, z1: 1, z2: 2, z3: 3, z5: 5 }

配列をオブジェクトに入れる

a = [ 1, 2, 3 ];
b = {
  z4: 4,
  ...a,
  z5: 5
};
console.log(b);

// -> Object { 0: 1, 1: 2, 2: 3, z4: 4, z5: 5 }

インデックスをキーとして挿入される。
オブジェクトを配列に入れることは(スプレッド演算子では)できない。

配列/オブジェクト同士の結合(スプレッド構文)

上記と同じ方法でスプレッド演算子を複数使うと配列の結合やオブジェクトのマージが可能になります。

ただ、この場合の結合/マージは1段階の深さで行われるため、多次元の配列/オブジェクトの結合/マージ(いわゆるディープマージ)は再帰的な仕組みが必要になります。

配列同士の結合

a = [ 1, 2, 3 ];
b = [ 4, 5, 6 ];
c = [ ...a, ...b ];

console.log(c);

// -> Array(6) [ 1, 2, 3, 4, 5, 6 ]

オブジェクト同士の結合(マージ)

a = {
  z1: 1,
  z2: 2,
  z3: 3
};
b = {
  z2: 4,
  z3: 5,
  z4: 6
};
c = { ...a, ...b };
console.log(c);

// -> Object { z1: 1, z2: 4, z3: 5, z4: 6 }

Object.assignと同じように同じkeyを上書きする。

多次元オブジェクトの結合(マージ)

a = {
  z1: 1,
  z2: {
    zz1: 2.1,
    zz2: 2.2
  },
  z3: [10, 11, 12],
  z4: 4
};
b = {
  z2: {
    zz2: 2.3,
    zz3: 2.4
  },
  z3: [13, 14, 15],
  z5: 5
};

// (Arrayでない)Objectの判定
const isObject = obj => (obj instanceof Object && !(obj instanceof Array));

// マージ用の再帰的関数
const mergeObj = (x1, x2) => {
  let mg = {...x1, ...x2};
  for (key in mg){
    if (key in x2) {
      if (isObject(mg[key])) {
        mg[key] = mergeObj(x1[key], x2[key]);
      } else if (Array.isArray(mg[key])) {
        mg[key] = [...x1[key], ...x2[key]];
      }
    }
  }
  return mg;
}

c = mergeObj(a, b);
console.log(c);

/*
  {
    z1: 1,
​    z2: {
      zz1: 2.1,
​​      zz2: 2.3,
​​      zz3: 2.4
    },
    ​z3: [ 10, 11, 12, 13, 14 15 ],
    z4: 4,
​    z5: 5
  }
​*/

配列の一部を末尾から抜き出す(レスト構文)

a = [ 1, 2, 3, 4, 5, 6 ];
[ , , ...b ] = a;

console.log(b);

// -> Array(4) [ 3, 4, 5, 6 ]

[...b, , ] = a;のように頭から抜き出すことはできない。
また同じような操作はオブジェクトに対してはできない。

配列/オブジェクト化(スプレッド構文)

文字列の配列/オブジェクト化

a = 'アイウエオ';
b = [ ...a ];
c = { ...a };
console.log(b, c);

1文字ずつを格納した配列、オブジェクトになる。

Nodelistなどの配列化

a = document.querySelectorAll('.item');
b = [ ...a ];
console.log(Array.isArray(a), Array.isArray(b));
// -> false true

可変長で引数を受け取る(レスト構文)

a = (z1, ...z2) => {
  console.log(z1, z2);
};
a(1, 2, 3, 4, 5);
// -> 1 Array(4) [ 2, 3, 4, 5 ]

配列を展開して関数に渡す(スプレッド構文)

a = (z1, z2, z3) => {
  console.log(z1, z2, z3);
};
b = [ 1, 2, 3 ]
a(...b);
// -> 1 2 3
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away