関数やメソッドの引数

《 初回公開:2023/04/01 , 最終更新:2023/04/12 》

【 目次 】

引数の数

JavaScriptの関数の引数の特異な点は、仮引数と実引数の数が異なっていてもそれなりに動作する事。

仮引数より実引数の数が多い場合、余った値は捨てられる。

function func(a, b) {
    console.log(`a = ${a}, b = ${b}`);
}
func(1, 2, 3);  // a = 1, b = 2

捨てられるといっても無くなっているわけではなくて、argumentsオブジェクトを使えば値を取り出す事ができる。

逆に仮引数より実引数の数が少ない場合、余分な引数にundefinedが代入される。

function func(a, b, c) {
    console.log(`a = ${a}, b = ${b}, c = ${c}`);
}
func(1, 2); // a = 1, b = 2, c = undefined

デフォルト引数

前項のサンプルコードのように実引数が与えられない場合にデフォルト引数を指定することができる。

function func(a, b, c = 3) {
    console.log(`a = ${a}, b = ${b}, c = ${c}`);
}
func(1, 2); // a = 1, b = 2, c = 3

可変長引数

可変長引数とは、関数に渡す引数の数が可変であり任意の数の引数を関数に渡す事ができる。
JavaScriptにおいて可変長引数をとる関数を記述するには、従来から使われてきたargumentsオブジェクトを使う方法と新たに導入された残余引数と呼ばれるレスト構文を使う方法の2種類が存在する。

残余引数 - Rest parameters

レスト構文を使った引数の指定は残余引数と呼ばれる。
関数の引数リスト内で ... という構文を使用して、可変長引数を表現する。

分割代入を利用して配列を関数に渡すと

function myFun([a, b, ...manyMoreArgs]) {
    console.log(`a = ${a}, b = ${b}, manyMoreArgs = ${manyMoreArgs}`);
}

myFun([1, 2, 3, 4, 5]);
// a = 1, b = 2, manyMoreArgs = 3,4,5

でも配列にする必要が無くて

// 残余引数(可変長引数関数)
function myFun(a, b, ...manyMoreArgs) {
    console.log(`a = ${a}, b = ${b}, manyMoreArgs = ${manyMoreArgs}`);
}

myFun(1, 2, 3, 4, 5);
// a, 1
// b, 2
// manyMoreArgs, [3, 4, 5] <-- 配列であることに注意
// 残りのパラメータは最後である必要があります

この例では、myFun関数の引数リストには ...manyMoreArgs というレスト構文を使用して、可変長引数を受け取っている。
manyMoreArgsには、関数に渡された3個目以降のすべての引数が配列として格納される。

レスト構文で述べたように残余引数は、あくまでも最後の引数に対してのみに使用できる。

残余引数にはデフォルトの引数値を指定する事ができないようで

function myFun(a, b = 5, ...manyMoreArgs) {
    console.log(`a = ${a}, b = ${b}, manyMoreArgs = ${manyMoreArgs}`);
}

myFun(1);   // a = 1, b = 5, manyMoreArgs = 

残余引数の前の引数にデフォルトの値を指定する事はできるが

function myFun(a, b, ...manyMoreArgs = [3, 4, 5]) {

このような引数の指定はできない。

可変長引数の例としてよく引き合いに出されるのは任意のn個の引数の合計を返すsum関数の例で、これをレスト構文を使って実装すると

function sum(...theArgs) {
    let total = 0;
    for (const arg of theArgs) {
        total += arg;
    }
    return total;
}

この関数はアロー関数とArray.prototype.reduceメソッドを利用するともっと簡潔になって

let sum = (...theArgs) => theArgs.reduce((total, arg) => total + arg);

arguments オブジェクト

arguments オブジェクトはすべての(アロー関数ではない)関数内で利用可能なローカル変数です。
arguments オブジェクトは Array ではありません。似ていますが、 Array のプロパティは length 以外ありません。たとえば、 pop() メソッドはありません。

前述のsum関数をargumentsオブジェクトを使って実装すると

function sum() {
    return Array.from(arguments).reduce((total, arg) => total + arg,0);
}

使われない引数a,b,c指定して下記のように記述する事もできるが、指定した値は捨てられるだけで

function sum(a, b, c) {

argumentsオブジェクトについてChatGPTにたずねてみると。

arguments オブジェクトは、JavaScriptの関数内で使用できる、ローカルなオブジェクトです。このオブジェクトは、関数が呼び出されたときに自動的に作成され、関数に渡された引数や、関数内で定義されたローカル変数などがプロパティとして格納されます。

arguments オブジェクトは、以下のような特徴があります。

arguments オブジェクトは、配列のようにインデックスでアクセスできます。
arguments オブジェクトは、length プロパティを持っており、渡された引数の個数を表します。
arguments オブジェクトは、配列のように、slice や forEach などのメソッドを使用することができます。
arguments オブジェクトは、配列ではないため、pop や push などの配列固有のメソッドを使用することができません。
...
ただし、arguments オブジェクトは、ECMAScript 2015(ES6)からは非推奨とされており、rest パラメータ構文や spread 構文などの新しい機能が導入されています。これらの機能を使用することで、可変長引数をより直感的に扱うことができるため、新しいコードでは arguments オブジェクトの使用を避けることが推奨されています。

おやおやChatGPTの回答もけっこう嘘が多くて、arguments オブジェクトは、配列ではないのでslice や forEach等のArrayクラスのメソッドは使えない。
使いたければ前述のコードのようにArray.fromメソッドを使って一旦,配列に変換する必要がある。

arguments オブジェクトを配列に変換するにはスプレッド構文を利用する事もできる。

function func() {
    let args = [...arguments];
    // let args = Array.from(arguments);と同じ

argumentsオブジェクトにはcalleeというプロパティあって、これについては「不思議の国のJavaScript オブジェクト指向に関するtips - 愚鈍人」を参照。

アロー関数

前述のように、残余引数はアロー関数にも有効であるが

let sum = (...theArgs) => theArgs.reduce((total, arg) => total + arg);
console.log(sum(1, 2, 3));  // 6

arguments オブジェクトはアロー関数内では使えない。

let sum = () => Array.from(arguments).reduce((total, arg) => total + arg);
// Uncaught ReferenceError: arguments is not defined at sum

名前付き引数

名前付き引数とは、関数呼び出しの際に、引数の名前を指定して値を渡す方法のことを指す。 名前付き引数を使用することで、引数の順序に依存せず、明示的に引数を渡すことができる。

javascriptには名前付き引数を指定する事はできないが、オブジェクトの分割代入を利用する事で名前付き引数と似たような機能を実現する事ができる。

function func({ a, b, c = 10 }) {
    console.log(`a = ${a}, b = ${b}, c = ${c}`);
}
func({ b: 1, a: 2 });   // a = 2, b = 1, c = 10

分割代入と関数を組み合わせるともっと複雑な事が可能。


最後に他のサイトの記事も参考に

ページのトップへ戻る