JavaScript④・関数

Image from Gyazo

CodePenの準備

CodePenにアクセスして,Penを作成し,タイトルを設定しましょう. Penのタイトルは「Chapter6」に設定しましょう.

https://codepen.io/

Image from Gyazo

関数

与えられた入力に対して,特定の処理を実行して結果を返す仕組みが 関数 です. 複雑な処理を関数として名前を付けることで, プログラムのどこからでも関数を呼び出すことが可能になります. 関数を定義するには,下記の方法があります.

functionで定義

一般的な関数の定義方法です. 上述したように関数は,入力に対して,特定の処理をして,結果を返します. 入力は 引数(ひきすう),結果は 返り値(かえりち) と呼びます(返り値は 戻り値 と表現することもあります).

関数の基本形

最初に引数や返り値を伴わないシンプルな関数の定義方法を確認しましょう. 関数名は自由に設定することができますが,先頭が小文字のキャメルケースで表現することが一般的です.

function 関数名(){
  実行する処理:
}

次のisEven関数は,変数numberが偶数かどうかを判定します. 偶数かどうかは,2で割った余りが0になるかどうかで判断することが出来ます. 0である場合はtrue,0でない場合はfalseを関数の結果として返します. ここで,number=12であるため,12 % 2 = 0となり,true(偶数)になることがわかります.

// 変数numberが偶数かどうかを判定する関数
function isEven(){
  let number = 12;
  let result = ((number % 2) == 0);
  document.write(`<p>result=${result}</p>`); // -> result=true
}

// isEven関数を呼び出す
isEven();

引数を利用した関数

引数は関数名の後の()の中に記述します. 複数の引数を指定したい場合は,カンマで区切って記述します.

function 関数名(引数1,引数2,...){
  実行する処理;
}

引数に指定された number が偶数かどうかを判定するisEven2関数を定義しましょう. 引数の値は,関数を呼び出すときに()の中に記述します.

// 引数numberが偶数かどうかを判定する関数
function isEven2(number){
  let result = ((number % 2) == 0);
  document.write(`<p>result=${result}</p>`);  // -> result=true
}

// isEven関数を引数を付けて呼び出す
let number = 12;
isEven2(number);

返り値を利用した関数

返り値はreturnの後に記述します. 関数を実行した結果として,返り値は戻されます.

function 関数名(引数1,引数2,...){
  実行する処理;
  return 返り値;
}

偶数の判定結果を返り値とするisEven3関数を定義しましょう. 関数の実行結果をresultに受け取ってから表示しています.

// 偶数の判定結果を返す関数
function isEven3(number){
  let result = ((number % 2) == 0);
  return result;
}

// isEven関数の帰り値を受け取る
let number = 12;
let result = isEven3(number);
document.write(`<p>result=${result}</p>`);  // -> result=true

アロー関数(無名関数)で定義

ES6で新たに アロー関数 の定義が可能になりました. functionで定義する関数とは異なり,関数に名前がないことから 無名関数 とも呼ばれます. 関数自体が変数に代入されることも大きな特徴です. この機能により,関数を引数としたり,関数を返り値とすることが可能になります(JavaScriptの大きな特徴です).

let 変数名 = (引数1, 引数2, ...) => {
  実行する処理;
  retun 返り値;
};

ここでは,引数に指定された number が奇数かどうかを判定する isOdd関数を定義しましょう. 奇数は2で割った余りが1になるかどうかで判断することが出来ます. 1である場合はtrue,1でない場合はfalseを関数の結果として返します.

// 引数が奇数かどうかを判定する関数
let isOdd = (number) => {
  let result = ((number % 2) == 1);
  return result;
}

// isOdd関数を呼び出す
let number = 12;
let result = isOdd(number);
document.write(`<p>result=${result}</p>`);  // -> result=false

アロー関数では,引数が1個の場合は()を省略出来ます. よって,(number)numberに書き換えることができます. また,実行する処理が1文である場合は{}が省略可能であり, 処理の結果が自動的に返り値とみなされるためreturnも不要です よって,((number % 2) == 1)と書き換えることができます. とてもシンプルな記述になりました.

// isOdd関数の定義を簡略化したisOdd2関数
isOdd2 = number => ((number % 2) == 1);

// isOdd2関数を呼び出す
let number = 12;
let result = isOdd2(number);
document.write(`<p>result=${result}</p>`);  // -> result=false

関数の便利な機能

ES6では関数定義に関する便利な機能が追加されています. ここでは,引数のデフォルト値可変長引数複数の返り値 について解説します.

引数のデフォルト値

例えば,引数で指定された name を出力する printName関数を考えます. 引数を指定せずに関数を呼び出すと,nameundefined(未定義) という状態です.

function printName(name){
  document.write(`<p>Your name is ${name}</p>`);
}

// 「Your name is Naoto」と出力される
printName("Naoto");

// 「Your name is undefined」と出力される
printName();

Image from Gyazo

このように,引数が指定されなかったとき,引数=デフォルト値の形式で記述することで, デフォルトで用いられる値を指定することができます.

function printName2(name="Takaaki"){
  document.write(`<p>Your name is ${name}</p>`);
}

// 「Your name is Naoto」と出力される
printName2("Naoto");

// 「Your name is Takaaki」と出力される
printName2();

Image from Gyazo

可変長引数

引数の前に...引数と記述することで,任意の数だけ引数を指定することが出来ます. 例えば,引数で与えられた複数の値から,奇数だけを出力する findOdd関数を考えます. 3つの値を指定するには,3つの引数を定義する必要があります.

function findOdd(n1, n2, n3){
  if(isOdd(n1)){ document.write(`<p>${n1}</p>`); }
  if(isOdd(n2)){ document.write(`<p>${n2}</p>`); }
  if(isOdd(n3)){ document.write(`<p>${n3}</p>`); }
}

findOdd(1, 2, 3);

Image from Gyazo

これを可変長引数で書き換えます. すると任意の数の値を引数で指定することができます. 引数は自動的に配列に変換されるため, for of文などで引数を取り出します.

function findOdd2(...numbers){
  for(let n of numbers){
    if(isOdd(n)){ document.write(`<p>${n}</p>`); }
  }
}

findOdd2(1, 2, 3, 4, 5);

Image from Gyazo

複数の返り値

関数の結果をreturnで返すとき,複数の値を返すには配列や連想配列を使うことで実現可能です. このとき,分割代入 を利用すると,変数に名前を付けて受け取ることができます. ここでは,幅(width)と高さ(height)を指定した四角形の周囲の長さと面積を計算する shapeRect関数を考えます.

function shapeRect(width, height){
  let length = 2*width + 2*height; // 周囲の長さ
  let area = width * height; // 面積
  return [length, area]; // 配列を返り値とする
}

返り値を配列として受け取る場合は, 周囲の長さはshape[0],面積はshape[1]に代入されています.

// 返り値を配列として受け取る
let shape = shapeRect(10, 20);
let length = shape[0];
let area = shape[1];
document.write(`<p>length=${length} area=${area}</p>`); // -> length=60 area=200

返り値を分割代入して受け取る場合は, 周囲の長さはlength,面積はareaに代入されています.

// 返り値を分割代入して受け取る
let length, area;
[length, area] = shapeRect(10, 20);
document.write(`<p>length=${length} area=${area}</p>`);  // -> length=60 area=200

アプリの確認

See the Pen Chapter6 by Naoto Mukai (@nmukai) on CodePen.

課題

半径を引数として受け取り, 円の周囲の長さ面積 を計算するshapeCircle関数を定義してください. このとき,円周率はMath.PIを用いてください. また,半径を20として計算したときの返り値を分割代入して受け取り,画面に出力してください. 課題を完成させたら,Penの ZIPファイルリンク を提出してください. 提出方法は初回のWebアプリの開発を参考にしてください.

参考書籍

愛知県名古屋市にある椙山女学園大学 文化情報学部 向研究室の公式サイトです. 専門は情報科学であり,人工知能やデータベースなどの技術要素を指導しています. この公式サイトでは,授業で使用している教材を公開すると共に, ベールに包まれた女子大教員のミステリアスな日常を4コマ漫画でお伝えしていきます. サイトに関するご意見やご質問はFacebookまたはTwitterでお問い合わせください.