6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2021年10月16日 JavaScript (JavaScript Primer) 関数と宣言①

関数宣言

関数とは、ある一連の手続き(文の集まり)を1つの処理としてまとめる機能です。 関数を利用することで、同じ処理を毎回書くのではなく、一度定義した関数を呼び出すことで同じ処理を実行できます。

// 関数宣言
function 関数名(仮引数1, 仮引数2) {
    // 関数が呼び出されたときの処理
    // ...
    return 関数の返り値;
}
// 関数呼び出し
const 関数の結果 = 関数名(引数1, 引数2);
console.log(関数の結果); // => 関数の返り値

関数でreturn文を省略した時の挙動

関数でreturn文が実行されると、関数内ではそれ以降の処理は行われません。 また関数が値を返す必要がない場合は、return文では返り値を省略できます。 return文の返り値を省略した場合は、未定義の値であるundefinedを返します。

function fn() {
  // 何も返り値を指定してない場合は`undefined`を返す
  return;
  
  // すでにreturnされているため、この行は実行されません
  // コンソールに"Hello"は表示されません。
  console.log("Hello");
}
console.log(fn()); // => undefined

関数が何も値を返す必要がない場合は、return文そのものを省略できます。 return文そのものを省略した場合は、undefinedという値を返します。

function fn() {
  // return文を書かない。
}

console.log(fn()); // => undefined

[ES2015] デフォルト引数

デフォルト引数(デフォルトパラメータ)は、仮引数に対応する引数が渡されていない場合に、デフォルトで代入される値を指定できます。 次のように、仮引数に対して仮引数 = デフォルト値という構文で、仮引数ごとにデフォルト値を指定できます。

可変長引数

可変長引数とは、固定した数ではなく任意の個数の引数を受け取れる引数のことです。

可変長引数を実現するためには、以下の2つの方法のどちらかを使います。

  • Rest parametersを使う。

  • 関数の中でのみ参照できるargumentsという特殊な変数を利用する。

以下で、2つの方法それぞれを説明します。

Rest parametersを使う

Rest parametersは、仮引数名の前に...をつけた仮引数のことで、残余引数とも呼ばれます。 Rest parametersには、関数に渡された値が配列として代入されます。

Rest parametersは関数の宣言時に、可変長引数を仮引数として提示することが出来ます。そうすることで引数を何個でも複数受け取ることができます。今回は配列変数をrestparametersとして定義することで複数の引数を配列として受け取りその中身を自動で順番に取り出して関数内で使うことが出来ます。

function fn(...args) {
    // argsは引数の値が順番に入った配列
    console.log(args); // => ["a", "b", "c"]
}
fn("a", "b", "c");

Rest parametersと通常の引数を、併用することもできます。併用する場合、末尾にRest parametersを設定します。

function fn(arg1, ...restArgs) {
    console.log(arg1); // => "a"
    console.log(restArgs); // => ["b", "c"]
}
fn("a", "b", "c");

Spread構文を使うと、配列やオブジェクトを展開することができます。 関数を呼び出す際に、Spread関数を使うと引数に配列変数を使って呼び出すことが出来ます。実際に渡される引数の値は、Spread関数で展開された配列変数の中身になります。

function fn(x, y, z) {
    console.log(x); // => 1
    console.log(y); // => 2
    console.log(z); // => 3
}
const array = [1, 2, 3];
// Spread構文で配列を引数に展開して関数を呼び出す
fn(...array);
// 次のように書いたのと同じ意味
fn(array[0], array[1], array[2]);

console.log(...array); // => 1, 2, 3

関数の中でのみ参照できるargumentsという特殊な変数を利用する

可変長引数を扱う方法として、argumentsという関数の中でのみ参照できる特殊な変数があります。 argumentsは関数に渡された引数の値がすべて入ったArray-likeなオブジェクトです。 Array-likeなオブジェクトは、配列のようにインデックスで要素へアクセスできます。 しかし、Arrayではないため、実際の配列とは異なりArrayのメソッドは利用できないという特殊なオブジェクトです。

function fn() {
    // `arguments`はインデックスを指定して各要素にアクセスできる
    console.log(arguments[0]); // => "a"
    console.log(arguments[1]); // => "b"
    console.log(arguments[2]); // => "c"
}
fn("a", "b", "c");

2つの方法がありますが、基本的にはRest parametersが推奨されています。

arguments変数は仮引数の定義とは関係なく、実際に渡された引数がすべて含まれています。 そのため、関数の仮引数の定義部分だけ見ても、実際に関数の要求する引数がわからないという問題を作りやすいです。 Rest parametersであれば、仮引数で可変長を受け入れるかが明確になります。 このように、可変長引数が必要な場合はarguments変数よりも、Rest parametersでの実装を推奨します。

仮引数とは、関数に定義されているパラメーターのことです。
一般的には、仮引数を関数内で定義して呼び出しの際に実引数を渡します。対して、arguments変数は、関数内で使えて、配列のように扱える複数の実引数の情報が全て含まれています。
そのため、arguments変数を使うと以下のような処理の流れになります。まず関数宣言時に仮引数で宣言した後に、呼び出し時に仮引数で引数を渡すのではなく、関数として実引数を渡す流れになります。
ただし、arguments変数は、Array Likeなだけで厳密なArrayではないため、実際の配列とは異なります。arguments変数を使うと、Arrayのメソッドは利用できないという点には注意しましょう。

参考

JavaScript Primer 関数と宣言