基礎

JavaScriptの分割代入(オブジェクト)入門|プロパティを変数に取り出す方法

オブジェクトの分割代入は、オブジェクトのプロパティを個別の変数に簡潔に取り出せるES6の構文です。配列の分割代入が「位置」で対応するのに対し、オブジェクトの分割代入は「プロパティ名」で対応します。APIレスポンスやコンポーネントのprops、関数の引数など、あらゆる場面で活躍します。

この記事では、基本的な使い方からリネーム、デフォルト値、ネストしたオブジェクトの分割、関数引数での活用まで、実践的に解説します。

基本的な使い方

オブジェクトの分割代入は、左辺に {} を使ってプロパティ名と同じ変数名を並べます。

JavaScript
const user = {
  name: '田中太郎',
  age: 30,
  email: 'tanaka@example.com',
  city: '東京'
};

// 基本的な分割代入
const { name, age, email } = user;
console.log(name);
console.log(age);
console.log(email);

// 必要なプロパティだけ取り出せる(cityは取り出していない)
// 順番は関係ない(プロパティ名で対応する)
const { city, name: userName } = user;
console.log(city);
console.log(userName);
実行結果
田中太郎
30
tanaka@example.com
東京
田中太郎

配列の分割代入と違い、順番は関係ありません。プロパティ名が変数名と一致するものが取り出されます。すべてのプロパティを取り出す必要はなく、必要なものだけピックアップできるのが便利です。

リネームとデフォルト値

プロパティ名とは異なる変数名で受け取りたい場合はコロン : でリネームできます。また、プロパティが存在しない場合のデフォルト値を = で指定できます。

JavaScript
const product = {
  product_name: 'ノートパソコン',
  price: 98000
};

// リネーム:product_name を name という変数で受け取る
const { product_name: name2, price } = product;
console.log(name2);
console.log(price);

// デフォルト値
const config = { theme: 'dark' };
const { theme, language = 'ja', fontSize = 14 } = config;
console.log(theme);
console.log(language);   // 存在しないのでデフォルト値
console.log(fontSize);   // 存在しないのでデフォルト値

// リネームとデフォルト値の組み合わせ
const { color: textColor = 'black' } = config;
console.log(textColor);
実行結果
ノートパソコン
98000
dark
ja
14
black

APIのレスポンスなど、プロパティ名がスネークケース(product_name)の場合に、キャメルケース(productName)の変数にリネームして受け取るパターンは実務でよく使います。

ネストしたオブジェクトの分割代入

JavaScript
const response = {
  status: 200,
  data: {
    user: {
      id: 1,
      name: '鈴木花子',
      address: {
        prefecture: '大阪府',
        city: '大阪市'
      }
    },
    token: 'abc123'
  }
};

// ネストした分割代入
const {
  status,
  data: {
    user: { name: userName2, address: { prefecture } },
    token
  }
} = response;

console.log(status);
console.log(userName2);
console.log(prefecture);
console.log(token);
実行結果
200
鈴木花子
大阪府
abc123

ネストが深くなると分割代入も複雑になります。3階層以上のネストは読みにくくなるため、段階的に分割するか、直接ドット記法でアクセスする方が良い場合もあります。

実践例:関数の引数での分割代入

JavaScript
// 関数の引数でオブジェクトを分割代入
function createUser({ name, age, role = '一般' }) {
  console.log(name + ' (' + age + '歳) - ' + role);
}

createUser({ name: '高橋', age: 25, role: '管理者' });
createUser({ name: '山田', age: 22 });

// オプション引数のパターン
function setupApp({ debug = false, port = 3000, host = 'localhost' } = {}) {
  console.log('サーバー起動: ' + host + ':' + port);
  console.log('デバッグモード:', debug);
}

setupApp({ port: 8080, debug: true });
setupApp();  // すべてデフォルト値

// 残余プロパティ(rest)
const { id, ...others } = { id: 1, name: '佐藤', age: 28, city: '福岡' };
console.log('ID:', id);
console.log('その他:', others);
実行結果
高橋 (25歳) - 管理者
山田 (22歳) - 一般
サーバー起動: localhost:8080
デバッグモード: true
サーバー起動: localhost:3000
デバッグモード: false
ID: 1
その他: { name: '佐藤', age: 28, city: '福岡' }

関数の引数で分割代入を使うと、呼び出し側でプロパティ名を明示するため、引数の順番を気にする必要がなくなります。オプション引数が多い関数では特に有効で、ReactコンポーネントのPropsもこのパターンで受け取ります。

computedプロパティ名も使える

変数をキーとして使う場合は const { [key]: value } = obj のようにブラケット記法が使えます。動的なプロパティ名の取り出しに便利です。

既存変数への分割代入は括弧が必要

letconst なしで既存の変数に分割代入する場合、{ a, b } = obj はブロック文と解釈されてエラーになります。({ a, b } = obj) のように全体を括弧で囲む必要があります。

まとめ

  • オブジェクトの分割代入は const { prop } = obj でプロパティを変数に取り出せる
  • { prop: newName } でリネーム、{ prop = defaultValue } でデフォルト値を指定できる
  • ネストしたオブジェクトも分割代入可能だが、深すぎると読みにくい
  • 関数の引数で使うと名前付きパラメータのように扱え、可読性が上がる
  • ...rest で残りのプロパティをまとめて取得できる