JavaScript | ES6+ 文法:分割代入 – ネスト分割

JavaScript
スポンサーリンク

ネスト分割とは何か

ネスト分割(ネストした分割代入)は、オブジェクトや配列の“入れ子構造”から、必要な値だけを階層に沿って取り出す書き方です。ここが重要です:左側のパターン(構造の形)に合わせて、右側のオブジェクト・配列から同じ位置やキーで値を引き出します。深くなりやすいので「段階的に」「安全に」取り出す工夫がポイントです。

const data = {
  ui: { theme: "dark", fontSize: 16 },
  api: { base: "/api", timeout: 5000 }
};

// 一気に取り出し
const { ui: { theme, fontSize }, api: { base, timeout } } = data;
console.log(theme, fontSize, base, timeout); // "dark" 16 "/api" 5000
JavaScript

段階的に分割する(読みやすさ優先)

ネストを一行に詰め込みすぎると読みにくくなります。ここが重要です:まず“上位の塊”を取り出し、次に“必要なプロパティ”へ絞ると見通しがよく、保守が楽になります。

const data = {
  user: { id: 7, profile: { name: "Alice", age: 20 } }
};

// 段階的に(推奨)
const { user } = data;
const { id, profile } = user;
const { name, age } = profile;
console.log(id, name, age); // 7 "Alice" 20

// 一行でも可能だが、長くなる
const { user: { id: uid, profile: { name: uname, age: uage } } } = data;
JavaScript

外側のデフォルトで“欠落”に備える(安全の鍵)

中間オブジェクトが undefined の可能性があるとき、外側に既定値({} や [])を置くと安全です。ここが重要です:未指定のまま深く潜るとエラーになりますが、外側既定値で“足場”を用意すれば落ちません。

const cfg = {}; // ui が無いかもしれない
const { ui: { theme = "light", fontSize = 16 } = {} } = cfg;
console.log(theme, fontSize); // "light" 16

// 配列の入れ子も同様
const point = [10]; // [x, [y, z]]
const [x = 0, [y = 0, z = 0] = []] = point;
console.log(x, y, z); // 10 0 0
JavaScript

名前変更(エイリアス)と既定値の併用

ネストでもプロパティ名を“自分の語彙”へ変えられます。ここが重要です:キー: 変数名 で別名、= 既定値 で欠けた値に備える。API 名を読みやすい変数へマッピングして、同時に安全性も確保します。

const res = {
  product: { product_id: 1, product_name: "  Apple  " },
  price: { jpy: 123456 }
};

const {
  product: { product_id: id, product_name: name = "" },
  price: { jpy: amount = 0 }
} = res;

console.log(id, name.trim(), amount.toLocaleString("ja-JP"));
// 1 "Apple" "123,456"
JavaScript

配列×オブジェクトのネストを“役割分担”で受ける

位置の情報は配列で、意味の情報はオブジェクトで受けると読みやすくなります。ここが重要です:配列は位置ベース、オブジェクトは名前ベース。混在構造でも落ち着いて分割できます。

// rows: [id, detailObj]
const rows = [
  [1, { name: "Apple", price: 100 }],
  [2, { name: "Banana", price: 200 }]
];

const view = rows.map(([id, { name, price }]) =>
  `${id}:${name.trim()} (${Math.round(price * 1.1)}円)`
);

console.log(view.join("\n"));
// 1:Apple (110円)
// 2:Banana (220円)
JavaScript

関数パラメータでのネスト分割(実務の定石)

関数の引数でネスト分割すると、必要項目・既定値・意図がシグネチャに現れて誤用が減ります。ここが重要です:引数そのものが未指定でも安全にするため、外側の既定値を必ず置く。

function renderCard(
  { product: { id, name = "" } = {}, price: { jpy = 0 } = {} } = {}
) {
  return `
  <div data-id="${id}">
    <h2>${name.trim()}</h2>
    <p>価格: ${jpy.toLocaleString("ja-JP")} 円</p>
  </div>
  `.trim();
}

console.log(renderCard({ product: { id: 1, name: "  Apple  " }, price: { jpy: 123456 } }));
JavaScript

残余の活用(“残り全部”をまとめる)

オブジェクトの残余(…rest)で、取り出し以外のプロパティをまとめられます。ここが重要です:ネストでも“主役だけ抜いて残りは渡す”設計で拡張に強くなります。

const cfg = { ui: { theme: "dark", fontSize: 16 }, api: { base: "/api" }, debug: true };
const { ui: { theme, ...uiRest } = {}, ...others } = cfg;

console.log(theme);   // "dark"
console.log(uiRest);  // { fontSize: 16 }
console.log(others);  // { api: { base: "/api" }, debug: true }
JavaScript

よくある落とし穴と回避策(重要ポイントの深掘り)

未定義の中間へ潜ってクラッシュ

対象が undefined のまま { x: { y } } のように潜るとエラー。外側既定値(= {}= [])を必ず置く。

// NG:ui が無いと落ちる
// const { ui: { theme } } = cfg;

// OK
const { ui: { theme = "light" } = {} } = cfg;
JavaScript

null には既定値が効かない

既定値は undefined にだけ発動。null も既定扱いにしたいなら、取り出し後に ?? で補正する。

const settings = { ui: { theme: null } };
const { ui: { theme } } = settings;
const safeTheme = theme ?? "light"; // null/undefined を "light" に
JavaScript

一行に詰め込みすぎて可読性が低下

長いネストは段階的に分割し、意味ごとに変数へ落とす。計算や整形は分割に書かず、補助関数へ。

const yen = n => `${n.toLocaleString("ja-JP")} 円`;
// 分割は“取り出し”、整形は関数へ分離
JavaScript

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

再代入で先頭が { だとブロックと解釈されるため、丸括弧で囲う。

let theme, base;
({ ui: { theme }, api: { base } } = { ui: { theme: "dark" }, api: { base: "/api" } });
console.log(theme, base); // "dark" "/api"
JavaScript

例題で理解を固める

// 1) 配列×オブジェクトのネスト:位置+意味で取り出す
const rows = [
  [1, { price: 100, meta: { tag: "fruit" } }],
  [2, { price: 200, meta: { tag: "fresh" } }]
];
const out = rows.map(([id, { price, meta: { tag } }]) => `${id}:${tag} (${Math.round(price * 1.1)}円)`);
console.log(out.join("\n"));

// 2) 設定の安全取り出し:外側既定値+内側既定値
const cfg = {};
const { ui: { theme = "light", fontSize = 16 } = {}, api: { base = "/api", timeout = 3000 } = {} } = cfg;
console.log(theme, fontSize, base, timeout);

// 3) 残余で拡張に強い分割
const user = { id: 7, profile: { name: "Alice", age: 20 }, role: "admin" };
const { profile: { name, ...profileRest } = {}, ...userRest } = user;
console.log(name);         // "Alice"
console.log(profileRest);  // { age: 20 }
console.log(userRest);     // { id: 7, role: "admin" }

// 4) 関数パラメータ:ネスト受け取り+既定値
function render({ product: { id = 0, name = "" } = {}, price: { jpy = 0 } = {} } = {}) {
  return `${id}:${name.trim()} (${jpy.toLocaleString("ja-JP")} 円)`;
}
console.log(render({ product: { id: 1, name: "  Apple  " }, price: { jpy: 123456 } }));
console.log(render()); // 0: (0 円)

// 5) 配列ネスト:欠けても安全に
const triple = [10, [20], 30];
const [a = 0, [b = 0, c = 0] = [], d = 0] = triple;
console.log(a, b, c, d); // 10 20 0 30
JavaScript

まとめ

ネスト分割の核心は「入れ子構造から、必要な値だけを“安全に”“読みやすく”取り出す」ことです。段階的分割で見通しを保ち、外側既定値で未定義の中間に備え、名前変更+既定値で自分の語彙へ整える。配列は位置、オブジェクトは意味で受ける役割分担が有効。重い処理は分割に書かず補助関数へ、再代入は括弧を忘れない。これを徹底すれば、初心者でもネスト構造を怖がらずに扱える ES6+ の分割代入が身につきます。

タイトルとURLをコピーしました