arguments 非対応とは何か
アロー関数は「自分専用の arguments(可変長引数の擬似配列)」を持ちません。ここが重要です:従来の function なら arguments で渡された全引数にアクセスできますが、アロー関数はそれができません。代わりに“設計的に正しい”手段である rest パラメータ(...args)を使います。例外的に、アロー関数が“通常の関数の内側”にある場合は、外側の function が持つ arguments を参照できます(レキシカルにキャプチャされるため)が、これは原則避けるべきです。
// 従来の function は arguments を持つ
function sum() {
return Array.from(arguments).reduce((s, n) => s + n, 0);
}
// アロー関数は arguments を持たない
const sumArrow = () => {
// return Array.from(arguments).reduce(...) // NG: arguments がない
return 0;
};
JavaScript正しい代替:rest パラメータ(…args)
rest パラメータは“受け取った引数を配列として受理”する構文で、アロー関数でも使えます。ここが重要です:arguments よりも型安全・可読で、配列メソッドをそのまま使えます。
// 可変長引数を安全に受け取る
const sum = (...nums) => nums.reduce((s, n) => s + n, 0);
console.log(sum(1, 2, 3)); // 6
// 先頭は必須、後続は任意も簡単
const tag = (label, ...parts) => `${label}:${parts.join("-")}`;
console.log(tag("id", 10, 20, 30)); // "id:10-20-30"
JavaScript複合パラメータとも組み合わせられます。分割代入やデフォルト引数との相性が良く、意図が明確になります。
const formatUser = ({ id, name = "" }, ...flags) =>
`${id}:${name.trim()}${flags.length ? ":" + flags.join(",") : ""}`;
JavaScript呼び出し側は spread(…)で渡す
呼び出し側が配列の要素を“引数として展開”するには spread を使います。ここが重要です:rest は“受け取り側”、spread は“渡し側”。両者を組み合わせると、柔軟で読みやすい可変長処理になります。
const nums = [10, 20, 30];
const sum = (...xs) => xs.reduce((s, n) => s + n, 0);
console.log(sum(...nums)); // 60(配列を展開して渡す)
JavaScript外側の arguments を“拾える”が原則使わない
アロー関数は自前の arguments を持ちませんが、通常の function の内側で書いた場合、その外側 function の arguments を参照できます。ここが重要です:動くが紛らわしく、保守性が下がるため推奨しません。rest に置き換えましょう。
function outer() {
// outer の arguments を内側のアローが参照してしまう例
const inner = () => Array.from(arguments).join("-");
return inner();
}
console.log(outer(1, 2, 3)); // "1-2-3"(動くが読みづらい)
// 推奨:outer も inner も rest にする
function outer2(...args) {
const inner = (...xs) => xs.join("-");
return inner(...args);
}
console.log(outer2(1, 2, 3)); // "1-2-3"
JavaScriptありがちな落とし穴と対策(重要ポイントの深掘り)
アロー関数で arguments を使おうとしてエラー(ReferenceError)や undefined な挙動に遭遇しがちです。対策は一貫して“rest に置き換える”。また、arguments は配列ではなく“擬似配列”なので、配列メソッドが直接使えず、Array.from やスプレッド変換が必要でした。rest は最初から配列なので余計な変換が不要です。さらに、arguments はすべての引数を無差別に含むため、意図が曖昧になりがち。関数のインターフェース(必要な引数・可変部分)をパラメータで明確化するほうが安全です。
// NG: アローで arguments を前提に書いてしまう
const concat = () => Array.from(arguments).join(""); // 失敗
// OK: rest で明示
const concat2 = (...parts) => parts.join("");
JavaScript実務レシピ(可変長と配列処理をスマートに)
可変長のバリデーション+計算
const average = (...nums) => {
const vals = nums.filter(n => Number.isFinite(n));
return vals.length ? vals.reduce((s, n) => s + n, 0) / vals.length : 0;
};
JavaScript先頭は固定、後続はオプションのパターン
const buildUrl = (base, ...params) =>
`${base}?` + params.map(encodeURIComponent).join("&");
console.log(buildUrl("/search", "q=js", "page=2")); // "/search?q=js&page=2"
JavaScript引数の“形”を明示(分割代入+rest)
const render = ({ id, name }, ...mods) =>
`${id}:${name}${mods.length ? " [" + mods.join(", ") + "]" : ""}`;
JavaScriptまとめ
アロー関数は arguments を持たないため、“可変長引数は rest(…args)を使う”が原則です。呼び出し側は spread(…)で配列を展開する。外側の arguments をキャプチャできても、読みづらく誤解を招くので避ける。rest は最初から配列で扱いやすく、型安全・可読性・保守性に優れます。これを徹底すれば、初心者でもアロー関数で柔軟かつ明快なインターフェースを設計でき、arguments 依存の罠から卒業できます。
