第11回 関数に関するいくつかのトピックTypeScriptで学ぶJavaScript入門(1/4 ページ)

プログラミング初心者向けのTypeScript入門連載。第11回は関数のさまざまな使い方について詳しく解説する。TypeScriptでプログラミングへの理解を一歩深めよう。

» 2015年06月04日 05時00分 公開
[羽山博]
TypeScriptで学ぶJavaScript入門
Insider.NET

 

「TypeScriptで学ぶJavaScript入門」のインデックス

連載目次

 前回は、TypeScriptの関数について基本的な事柄を説明した。今回は引き続き、関数のより詳細な利用方法を見ていく。具体的には、オプションの引数、引数の既定値、オーバーロード、ジェネリック、クロージャーといった機能がテーマとなる。

オプションの引数

 関数を定義するときには、仮引数としてオプションの引数が指定できる。仮引数をオプションにした場合、関数を呼び出すときには、その仮引数に対応する実引数は指定することも、省略することもできる。

 簡単な例で見てみよう。単価(price)と数量(amount)を基に、金額を求める関数があるものとする。ただし、割引率(discount)が指定されている場合は、それだけ割り引くこととしよう。つまり、割引率は省略可能というわけだ。

 関数の定義と呼び出しのためのコードは以下の通り。

function calcCost(price: number, amount: number, discount?: number): number { // (1)
  if (discount) {  // (2)
    return price * amount * (1 - discount); // (3)
  } else {
    return price * amount;   // (4)
  }
}
alert(calcCost(1200, 10));   // (5)
window.close();


 (1)のように、省略可能な引数を定義するには、仮引数の名前の後に「?」を付けて表す。関数の呼び出し時に、(5)のように実引数を省略すると仮引数discountは「undefined」となる。そこで、(2)のif文を使えば、仮引数discountの指定が省略されているかどうかが判定できるというわけだ。仮引数discountが利用できれば(3)の文が実行され、利用できなければ(4)の文が実行される。

 実行例は以下の通り。この場合、alertメソッド呼び出し内にあるcalcCost関数呼び出しでは最後の実引数が省略されているので、割り引きは行われず、結果は「12000」となる。

図1 関数の実行例 図1 関数の実行例
実引数の指定を省略して関数を呼び出した場合の結果。

 もちろん、(5)のコードにあるcalcCost関数呼び出しを以下のように書き換え、全ての実引数を指定して呼び出せば、1200×10×(1−0.1)という計算が実行されるので、結果は1割引の「10800」となる。

calcCost(1200, 10, 0.1)

省略可能な引数を省略せずに関数を呼び出した場合

 なお、(2)の文は以下のように書いてもよい。

if (discount != undefined)

引数が省略された場合はundefinedとなるので、「==」や「!=」を使って判定してもよい

 ここでもう一つ、可変長(可変個)引数について説明しておこう。可変長引数を使うと、関数を呼び出すときに異なる数のデータを渡せる。以下に例を示す。

function paramtest(arg1: number, ...restparam: number[])
{
  return "first item of restparam: " + restparam[0] +
         "\nlength of restparam: " + restparam.length;
}
alert(paramtest(1, 2, 3, 4, 5));
window.close();


 paramtest関数の第1引数(arg1)は省略不可能であり、次のrestparamが可変長引数となっている。可変個のデータを受け取る仮引数はこのように「...」に続けてその名前を記述する。この仮引数の型は配列型でなければならず、特に指定をしない場合にはany[]型となる(上ではnumber[]型となるように指定)。この場合、関数呼び出し時に省略不可能な引数に割り当てられたもの以外の実引数が配列としてrestparamに割り当てられる。例えば、「paramtest(1, 2, 3, 4, 5)」という呼び出しでは、「1」が仮引数arg1に、残りの2〜5が配列としてrestparamに割り当てられるわけだ。関数中で使用されているrestparam[0]やrestparam.lengthの値がどうなるかは、コードを実行して確認してみてほしい。

 なお、省略可能な引数や可変長引数を定義するときには、一つ注意点がある。それは、省略可能な引数や可変長引数は、指定する順序が決まっているということだ。省略可能な引数は省略できない引数の後に書き(複数あってもよい)、可変長引数がある場合には引数リストの最後に指定する。可変長引数は一つしか書けないことにも注意しよう。省略可能な引数や可変長引数の後に、省略できない引数を書くとエラーになる。

 これらの引数を全て記述した場合の例は、引数の既定値を設定する方法を示した後で紹介することとしよう。

引数の既定値を設定する

 省略可能な引数には既定値が設定できる。そのためには、仮引数の名前の後に「=既定値」を指定すればよい。その場合、仮引数の名前の後に「?」は書かなくてもいい。先ほどのcalcCost関数を書き換えてみよう。

function calcCost(price: number, amount: number, discount = 0): number { // (1)
  return price * amount * (1 - discount);
}
alert(calcCost(1200, 10));
window.close();


 この例では、仮引数discountの既定値は0となる(割引率は0となる)。従って、if文を使わなくても上のようなコードで計算ができる。ここで、仮引数discountにはデータ型を指定していないが、既定値として0を代入しているので、型推測の機能によりnumber型と見なされる。

 引数の指定方法のまとめに代えて、省略できない引数、省略可能な引数、可変長引数を全て指定した例も見ておこう。

function paramtest(arg1: number, arg2: number = 2, ...restparam: number[]) {
    return "arg1: " + arg1 +
           "\narg2: " + arg2 +
           "\nfirst item of restparam: " + restparam[0] +
           "\nlength of restparam: " + restparam.length;
}
alert(paramtest(1, undefined, 3, 4, 5)); // (1)
window.close();


 ここでは、(1)に注目してほしい。省略可能な引数を省略しようとしても、以下のような記述はできない。

alert(paramtest(1, , 3, 4, 5));

省略可能な引数が最後の引数でないときには、単純に省略してしまうとエラーになる(誤った書き方)

 このような場合は、(1)のように、引数が省略されていることを示すために「undefined」と記述する必要がある。このようにしても、関数の定義で既定値が設定されているので、arg2の値は2になる。コードを実行して確かめてみるといいだろう。

 ここまで、関数に渡せるさまざまな引数について見てきた。次に関数のオーバーロードという機能について説明する。

       1|2|3|4 次のページへ

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。