JavaScriptの分割代入の使い方

2021年1月22日JavaScript

一度配列でグループ化したけど、やっぱり別々に管理したいとなった場合、分割代入 (Destructuring assignment) が使えます。
分割代入とは、オブジェクトから特定のプロパティを抽出して宣言を行うことです。
let {x,y} ~ object;とするとx,yが抽出されます。
具体的に下の例をみてみましょう。

分割代入の基本的な使い方

  'use strict';
//具体例1
{
const arr = [1, 2, 3];
  //分割代入を使わず、ひとつずつ変数に代入する
  const a = arr[0];
  const b = arr[1];
  const c = arr[2];
  console.log(a, b, c);

  //分割代入を使ったやり方
  const [x, y, z] = arr;
  console.log(x, y, z);
}

const [x, y, z] =というのは、いっけんすると配列のようにみえますが、配列ではありません。
=の左辺に[]がきたときは、分割代入であって配列ではないことを理解しておきましょう。

分割代入で一部の値を取り出したい場合

  'use strict';
//具体例2
  {
    const numbers = [10, 20, 30, 40, 50];
    //30以外を取り出したい。分割代入を使う。
    const [a, b, , d, e] = numbers;
    console.log(a); //10
    console.log(b); //20
    console.log(d); //40
    console.log(e); //50
  }

5つ中4つを分割して、30以外をそれぞれ定数に格納しています。
30以外を取り出したい。、 [a, b, , d, e]というように、空白にするだけでOKです。

分割代入で一部の値を取り出して、残りは残しておきたい場合

例えば、最初の2つだけ分割して、残りは残しておきたいという場合はどうすればいいのでしょうか?
その場合、配列として残して置きたい値のところに、「…配列名」と書きます。

「…配列名」とすればスプレッド構文と見た目は同じなのですが、これは残りを格納するのでレスト構文と呼ばれています。
具体的に使い方をみてみましょう。

  'use strict';
  {
    const numbers = [10, 20, 30, 40, 50];
    //やっぱりそれぞれを定数で定義したい。
    const [a, b, ...otherNumbers] = numbers; //分割代入
    console.log(a); //10
    console.log(b); //20
    console.log(otherNumbers); //[30, 40, 50]
  }

このように、a,bには分割した値が格納されて、レスト構文を使ってotherNumbersにそれ以外が格納されています。

分割代入は値の交換に便利

分割代入は値の交換をするときにもよく使われます。

xとyの値を交換したい場合、たとえば[a, b] = [b, a]と書くだけでOKになります。

  'use strict';
//分割代入を使用した場合
  {
    let a = 10;
    let b = 100;
    [a, b] = [b, a];
    console.log(a);//100
    console.log(b);//10
  }
{
//分割代入を使用しない場合
{
  let a = 10;
  let b = 100;
  const temp = a;
  a = b;
  b = temp;
  console.log(a);//100
  console.log(b);//10
  }
}

このように、分割代入を使用しない場合は、一時的に定数を用意して入れ替える必要があります。
分割代入のほうがとても簡単なことがわかります。

分割代入で関数から2つのリターンする値を受け取る方法

分割代入で関数から2つのリターンする値を受け取る方法は次の通りです。


const restaurantS = {
  name: 'レストランsakaso',
  location: '尼崎、日本',
  categories: ['中華', '和食', 'フレンチ', 'イタリアン'],
  starterMenu: ['シーザーサラダ', '大根サラダ', '青じそサラダ', 'チキンサラダ'],
  mainMenu: ['カレー', 'ハンバーグ', 'スパゲッティ'],

  order: function (starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },
};

const [starter, main] = restaurantS.order(2,0); //青じそサラダ、カレーが配列の値になる。
console.log(starter, main);

このように、オブジェクトに関数orderを作ってreturnと引数を使うことで、簡単にセットメニューを作ることができます。

ネストされた配列の場合

ネストされた配列の場合で分割代入を使って値を取り出す方法を紹介します。


// ネストされた配列の場合
{
const nested = [1, 2, [3, 4]];
const [a, b] = [nested[0], nested[2]]; //これでもいい。
console.log(a,b); //定数1と [3, 4]という配列
const [i, ,j] = nested;
console.log(i, j); //定数1と [3, 4]という配列

//ネストの中の値を取り出す場合

const [d, ,[e,f]] = nested;
console.log(d,e,f); //1, 3, 4というそれぞれの定数。
}

分割代入の変数にデフォルト値を設定する方法

分割代入の変数にデフォルト値を設定する方法を紹介します。


const [g, h, i] = [5,6];
console.log(g,h,i); //5,6,undefinedが返される。

const [j=2, k=2, l=2] = [5,6];
console.log(j, k, l); //5,6,2が返される。

上のように、デフォルト値を設定していないとundefinedが返されます。
それを防ぎたい場合、[j=2, k=2, l=2]とすることで、2というデフォルト値を設定することができます。

分割代入でオブジェクトから値を取り出す方法

オブジェクトの場合は、{}を使います。
const {} = という左辺にきたときは、それはオブジェクトではなく、分割代入です。


{
const restaurantS = {
  name: 'レストランsakaso',
  location: '尼崎、日本',
  categories: ['中華', '和食', 'フレンチ', 'イタリアン'],
  starterMenu: ['シーザーサラダ', '大根サラダ', '青じそサラダ', 'チキンサラダ'],
  mainMenu: ['カレー', 'ハンバーグ', 'スパゲッティ'],

  openingHours: {
    thu: {
      open: 12,
      close: 22,
    },
    fri: {
      open: 11,
      close: 23,
    },
    sat: {
      open: 0, // Open 24 hours
      close: 24,
    },
  },
  order: function (starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },
};
// 上から、name、categories、openingHoursを取り出したいとします。
//オブジェクトはキーをもっているため、順番関係なく指定することができます。
const {name, openingHours, categories} = restaurantS;
console.log(name);
console.log(openingHours);
console.log(categories);

//プロパティ名を変更したいとき
const {name: restaurantName, openingHours: hours, categories: tags} = restaurantS;
console.log(restaurantName);
console.log(hours);
console.log(tags);
}

分割代入を使って、オブジェクトのプロパティ名を変更したいときは、上のように{元のプロパティ名: 新しいプロパティ名}というようにします。
これは、サードパーティのAPIを活用するときにとても役に立つので知っておきましょう。

分割代入を使って、オブジェクトの初期値を設定したい場合

分割代入を使って、オブジェクトの初期値を設定したいときは次のように{元のプロパティ名:新しい名前}とします。


{
const restaurantS = {
  name: 'レストランsakaso',
  location: '尼崎、日本',
  categories: ['中華', '和食', 'フレンチ', 'イタリアン'],
  starterMenu: ['シーザーサラダ', '大根サラダ', '青じそサラダ', 'チキンサラダ'],
  mainMenu: ['カレー', 'ハンバーグ', 'スパゲッティ'],

  openingHours: {
    thu: {
      open: 12,
      close: 22,
    },
    fri: {
      open: 11,
      close: 23,
    },
    sat: {
      open: 0, // Open 24 hours
      close: 24,
    },
  },
  order: function (starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },
};
const {menu = [], starterMenu:firstMenu = []} = restaurantS;
console.log(menu, firstMenu);
}