目次
よく使う配列の分割代入パターン
1. 基本的な要素取得
// 配列の要素を変数に代入
const [first, second] = [1, 2, 3];
console.log(first); // 1
console.log(second); // 2
// 変数の交換(最頻出パターン)
let a = 1, b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1
2. 要素のスキップ
// 必要な要素のみ取得
const [first, , third] = [1, 2, 3];
console.log(first, third); // 1 3
3. デフォルト値
// 要素が存在しない場合の初期値
const [x = 0, y = 0] = [10];
console.log(x, y); // 10 0
4. 残余要素(...rest)
// 最初の要素と残り全て
const [head, ...tail] = [1, 2, 3, 4, 5];
console.log(head); // 1
console.log(tail); // [2, 3, 4, 5]
よく使うオブジェクトの分割代入パターン
1. プロパティの取得
// 同じ名前の変数で取得
const { name, age } = { name: 'Alice', age: 25, city: 'Tokyo' };
console.log(name, age); // 'Alice' 25
2. 変数名の変更
// 異なる変数名で取得
const { name: userName, age: userAge } = { name: 'Bob', age: 30 };
console.log(userName, userAge); // 'Bob' 30
3. デフォルト値
// プロパティが存在しない場合の初期値
const { x = 10, y = 20 } = { x: 5 };
console.log(x, y); // 5 20
4. 残余プロパティ
// 特定のプロパティを除いた残り全て
const { name, ...otherProps } = { name: 'Charlie', age: 28, city: 'Osaka' };
console.log(name); // 'Charlie'
console.log(otherProps); // { age: 28, city: 'Osaka' }
5. ネストしたプロパティ
// よく使うパターン:ユーザー情報の取得
const user = {
profile: { name: 'David', email: 'david@example.com' },
settings: { theme: 'dark' }
};
const { profile: { name, email } } = user;
console.log(name, email); // 'David' 'david@example.com'
関数パラメータでの分割代入
関数パラメータとしての配列分割代入
// 配列を受け取って分割代入
function processCoordinates([x, y, z = 0]) {
console.log(`X: ${x}, Y: ${y}, Z: ${z}`);
}
processCoordinates([10, 20]); // X: 10, Y: 20, Z: 0
// 複数の戻り値を返す関数
function getMinMax(numbers) {
return [Math.min(...numbers), Math.max(...numbers)];
}
const [min, max] = getMinMax([1, 5, 3, 9, 2]);
console.log(min, max); // 1 9
関数パラメータとしてのオブジェクト分割代入
// オプション引数パターン
function createUser({ name, age, email = 'no-email' }) {
return { name, age, email };
}
const user = createUser({ name: 'Charlie', age: 28 });
console.log(user); // { name: 'Charlie', age: 28, email: 'no-email' }
// デフォルトパラメータとの組み合わせ
function fetchData({ url, method = 'GET', timeout = 5000 } = {}) {
console.log(`${method} request to ${url} with ${timeout}ms timeout`);
}
fetchData(); // GET request to undefined with 5000ms timeout
fetchData({ url: '/api/users', method: 'POST' });
ネストした構造の分割代入
ネストした配列
const nestedArray = [[1, 2], [3, 4], [5, 6]];
// 2次元配列の分割代入
const [[a, b], [c, d]] = nestedArray;
console.log(a, b, c, d); // 1 2 3 4
// 深いネストの場合
const deepNested = [[[1, 2]], [[3, 4]]];
const [[[first]]] = deepNested;
console.log(first); // 1
ネストしたオブジェクト
const user = {
id: 1,
profile: {
name: 'David',
contact: {
email: 'david@example.com',
phone: '123-456-7890'
}
},
preferences: {
theme: 'dark',
language: 'ja'
}
};
// ネストしたプロパティの分割代入
const {
id,
profile: {
name,
contact: { email, phone }
},
preferences: { theme }
} = user;
console.log(id, name, email, phone, theme);
// 1 'David' 'david@example.com' '123-456-7890' 'dark'
混在パターン(配列 + オブジェクト)
const data = [
{ name: 'Alice', scores: [85, 92, 78] },
{ name: 'Bob', scores: [90, 88, 95] }
];
// 配列の中のオブジェクトを分割代入
const [
{ name: firstName, scores: [score1] },
{ name: secondName, scores: [, , score3] }
] = data;
console.log(firstName, score1); // 'Alice' 85
console.log(secondName, score3); // 'Bob' 95
実践的なユースケース
API レスポンスの処理
// API レスポンスの分割代入
const apiResponse = {
data: {
users: [
{ id: 1, name: 'Alice', active: true },
{ id: 2, name: 'Bob', active: false }
]
},
meta: { total: 2, page: 1 }
};
const {
data: { users },
meta: { total }
} = apiResponse;
// アクティブなユーザーのみ抽出
const activeUsers = users
.filter(({ active }) => active)
.map(({ name }) => name);
console.log(activeUsers); // ['Alice']
React での状態管理
// React Hooks での分割代入例
const [count, setCount] = useState(0);
const [{ loading, data, error }, setState] = useState({
loading: false,
data: null,
error: null
});
// useEffect の依存配列での分割代入
useEffect(() => {
// 処理
}, [count, loading]);
設定オブジェクトの処理
// 設定の分割代入とマージ
const defaultConfig = {
api: {
baseURL: 'https://api.example.com',
timeout: 5000,
retries: 3
},
ui: {
theme: 'light',
language: 'en'
}
};
function createConfig(customConfig = {}) {
const {
api: { baseURL = defaultConfig.api.baseURL, timeout = defaultConfig.api.timeout } = {},
ui: { theme = defaultConfig.ui.theme } = {}
} = customConfig;
return {
api: { baseURL, timeout },
ui: { theme }
};
}
const config = createConfig({
api: { timeout: 10000 },
ui: { theme: 'dark' }
});
配列操作での分割代入
// 配列の先頭と末尾を分離
function processQueue(queue) {
if (queue.length === 0) return;
const [current, ...remaining] = queue;
console.log(`Processing: ${current}`);
if (remaining.length > 0) {
processQueue(remaining);
}
}
// オブジェクトの配列での分割代入
const employees = [
{ name: 'Alice', department: 'Engineering', salary: 80000 },
{ name: 'Bob', department: 'Marketing', salary: 60000 },
{ name: 'Charlie', department: 'Engineering', salary: 75000 }
];
// 部署別グループ化
const engineeringTeam = employees
.filter(({ department }) => department === 'Engineering')
.map(({ name, salary }) => ({ name, salary }));
ベストプラクティス
可読性を重視した書き方
// ❌ 複雑すぎる分割代入
const { a: { b: { c: { d } } } } = complexObject;
// ✅ 段階的な分割代入
const { a } = complexObject;
const { b } = a;
const { c } = b;
const { d } = c;
// または中間変数を使用
const { a: nestedA } = complexObject;
const { b: { c: { d } } } = nestedA;
TypeScript での型安全性
// 型定義と分割代入
type User = {
id: number;
profile: {
name: string;
email?: string;
};
};
function processUser(user: User) {
const {
id,
profile: { name, email = 'no-email' }
} = user;
// 型安全な処理
console.log(`User ${id}: ${name} (${email})`);
}
エラーハンドリング
// 安全な分割代入
function safeDestructure(data) {
try {
const { user: { profile: { name } } } = data || {};
return name;
} catch (error) {
console.error('分割代入エラー:', error);
return null;
}
}
// Optional chaining との組み合わせ(ES2020+)
const name = data?.user?.profile?.name;
if (name) {
const { length } = name; // 安全に分割代入
}