LoginSignup
2
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-11-30

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

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

配列を配列に入れる

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
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4