メインコンテンツまでスキップ

関数

処理の共通化

数学における関数は、数と数の関係のようなものですが、JavaScriptをはじめとしたプログラミング言語の文脈における関数は、基本的にはのまとまりに名前を付けたものです。

// 関数を定義しておけば
function greet() {
document.write("Hello World!");
}

// 後から呼び出すことができる
greet();
greet();

上のプログラムにおいて、functionキーワードから始まる部分は関数を定義するための制御構文です。関数定義では、functionキーワードに続けて関数名、かっこを記述します。この後、関数内で実行したい処理を波かっこの中に記述していきます。

関数を定義すると、関数名に続けてかっこを記述することにより、その関数を実行できるようになります。

このプログラムでは、greet関数が2回呼び出されているので、ブラウザにHello World!が2つ表示されます。

引数

関数の振る舞いを呼び出し時に変更するため、関数引数を与えることができます。 引数には任意のが指定できます。

function greet(greetingType, myName) {
document.write("Good " + greetingType + ", " + myName + "!");
}

greet("morning", "佐藤");

関数定義では、関数名直後のかっこ内に引数名をコンマ区切りで設定できます。 上のプログラムでgreet関数は、greetingTypemyNameという名前の引数をとります。 関数定義の中では、これらは変数のように振舞います。

呼び出し側では、括弧の中に関数渡す引数を指定します。このプログラムを実行すると、ブラウザにGood morning, 佐藤!が表示されるでしょう。

引数

戻り値

関数呼び出しはの一種です。 関数定義内でreturn文を用いると、関数の実行が停止され、関数呼び出し評価結果が確定します。 この値を戻り値と呼びます。 ある戻り値として設定して関数の実行を終了することを、関数がその返すと表現します。

function add(a, b) {
const sum = a + b;
return sum;
}

document.write(add(3, 4));

上の例の6行目で、add(3, 4)評価されると、a = 3, b = 4としてadd関数が実行されます。add関数の中でconst sum = a + b;が実行されると、a + b評価され、7になります。これにより、sum7が代入されます。 次の行return sum;add関数変数sum評価した結果である、7返します。 そしてadd(3, 4)評価結果が7となります。

ヒント

return文が実行された時点で関数の処理が終了するため、次のように書くことでif〜else文&& (AND) 演算子の繰り返しを避けつつ、複数の条件のついた処理を実行することができます。

let age = 21;
let hasDriverLicense = true;
let isDrunk = true;
function tryToDrive() {
// if 文で実行する式が一行だけの場合、{} を省略できます。
if (age < 18) return;
if (!hasDriverLicense) return;
if (isDrunk) return;
document.write("車を運転できます。");
}

確認問題

引数を2つとり、その積を戻り値として返す関数multiplyを定義してください。

解答例: 2つの積
function multiply(a, b) {
const result = a * b;
return result;
}

document.write(multiply(3, 4));

変数スコープ

関数や if 文などのブロック内で宣言された変数は、そのブロック内でのみ有効です。

このような、変数が有効な範囲のことを、その変数スコープと呼んでいます。

const age = 18;

if (age >= 20) {
const message = "お酒が飲めます";
} else {
const message = "お酒は飲めません";
}

document.write(message); // エラー: message は定義されていません
function setAnswer(num) {
const answer = num;
}

setAnswer(42);

document.write(answer); // エラー: answer は定義されていません

関数外で宣言された変数関数内でも利用できます。

let guestCount = 0;

function greet() {
guestCount += 1;
document.write("あなたは" + guestCount + "人目のお客様です。");
}

greet(); // あなたは1人目のお客様です。
greet(); // あなたは2人目のお客様です。

この例における、greet関数は、呼び出されるたびにguestCountに1を加えています。

複合代入演算子

複合代入演算子 は、計算と代入を同時に行うことができる演算子です。

x += yは、x = x + yという意味になります。他にも-=*=などの演算子が定義されています。x -= yx = x - yx *= yx = x * yという意味になります。

guestCount += 1;

は以下の文のように読み替えられます。

guestCount = guestCount + 1;
変数スコープ

スコープが終わった変数は、その時点で破棄されます。

let outer = 0;

function increment() {
let inner = 0;
outer += 1;
inner += 1;
document.write(outer); // 1ずつ増える
document.write(inner); // 常に1
}

increment();
increment();

基礎演習

最大値

引数を2つとり、そのうち大きい数を返す関数maxを定義してください。

ヒント

if文を使って、aが大きい場合とbが大きい場合で処理を書き分けます。

解答例: 大きい数
function max(a, b) {
if (a > b) {
return a;
} else {
return b;
}
}
注記

a > btrueの場合、if文内部のreturnで関数実行が中断されるため、elseキーワードは必ずしも必要ではありません。そのため、次のように書くこともできます。

function max(a, b) {
if (a > b) {
return a;
}
return b;
}

中級演習

携帯電話料金

携帯電話料金を計算する関数を作ってみましょう。

function calculateCost(monthlyDataUsage) {
// ここに処理を書く
}

document.write(calculateCost(3.5));

calculateCostは、引数に月間転送量monthlyDataUsageを取り、その月の携帯電話料金を戻り値として返す関数です。携帯電話料金は、下のルールで決定されるとします。

  • 月間転送量 < 5.0 (GB) のとき、携帯電話料金は 月間転送量 × 600 (円 / GB)
  • 月間転送量 >= 5.0 (GB) のとき、携帯電話料金は 3000 (円)
解答例: 携帯電話料金
function calculateCost(monthlyDataUsage) {
if (monthlyDataUsage < 5.0) {
return monthlyDataUsage * 600;
}
return 3000;
}

document.write(calculateCost(3.5));