[JavaScript General] JavaScript における function 引数のあれこれ

初期値、可変長、名前付き、必須、関数。

分かる範囲で整理。

Default Parameter

ES2015 から初期値の設定ができるようになった。

function loop(func, count = 3) {
  for (let i = 0; i < count; i++) {
    func();
  }
}
loop(function(){console.log('hello')}); // hello hello hello

Rest Parameter

可変長引数は arguments を利用して書く必要があった。

arguments はすべての関数内で利用可能なローカル変数です。arguments オブジェクトを使うことにより、関数内で関数の引数を参照できます。

ES2015 から、可変長引数を受け取る事ができる。

numbers に [1,2,3,4] が入り、結果 10 となる.

function sum(...numbers) {
  return numbers.reduce(function(a, b) { return a + b; });
}
console.log(sum(1, 2, 3, 4)); // 10

いろいろあるよう。

引数の数をチェックする

arguments.length を利用していた。

function f(x, y) {
  if (arguments.length > 2) { throw new Error(); }
  var x = arguments[0];
  var y = arguments[1];

ES2015では、レストパラメータで受け取って、変数へ分割代入できる。

function f(...args) {
  if (args.length > 2) { throw new Error(); }
  let [x, y] = args;

Named parameter

名前付きパラメータは、args.path といった形で扱っていた。

function showPanel(args) {
  if (args.path === undefined) { throw {name: 'ArgsMissing', message: 'Missing parameter'}; }
  if (args.height === undefined) { args.height = 200; }
  if (args.width === undefined) { args.width = 300; }

ES2015 から関数引数の分割代入が可能になったので、このように書ける。

function showPanel2({path, height = 200, width = 300} = {}) {
  if (path === undefined) { throw new Error('Missing parameter'); }

See the Pen JavaScript ES2015 Named Parameters by DriftwoodJP (@DriftwoodJP) on CodePen.

Required Parameter

受け取った Parameter が undefined かどうかをチェックする。

function getArea(r_width, o_height = 1) {
  // Required params
  if (r_width === undefined) {
    throw { name: 'ArgsMissing', message: '幅が指定されていません。'}
  }
  return r_width * o_height;
}
try {
  console.log(getArea(10, 5)); // 50
  console.log(getArea(10));    // 10
  console.log(getArea());      // error
} catch(e) {
  console.log(e.message);
}

基本的な考え方は変わらない模様。
ES2015 から、前述のディフォルト値を利用してこんな書き方ができる。

See the Pen JavaScript ES2015 Required parameters by DriftwoodJP (@DriftwoodJP) on CodePen.

Higher-order Functions, aka Callback Functions

関数を引数にとる、関数を戻り値にとる関数を「高階(こうかい)関数」と呼ぶ。

以下の場合、

  • 関数 benchmark() は、引数として関数 proc を受け取る 高階関数 となる。
  • 呼び出し先の関数で呼び出される関数 proc を コールバック関数 と呼ぶ。
  • 再利用の必要がないのでコールバック関数を 関数リテラル(匿名関数) の形式で受け渡している。JavaScript 的な表現である。
function benchmark(proc) {
  var start = new Date();
  proc();
  var end = new Date();
  return end.getTime() - start.getTime();
}
console.log(
  benchmark(function() {
    var x = 15;
    for (var i = 0; i < 1000000; i++) {
      x *= i;
    }
  })
);
  • 高階関数は、イベント処理や非同期処理のためのライブラリでよく利用される記法。

Promise と関わってくる。