function
関数(function)
「関数って何?」
基本的には数学で出てくる関数(f(x)など)と同じものと思えば良い。
例えば数学における以下の関数は
以下のような関数で実装できる
function f(x) {
return x ** 2 + x * 2 + 1
}
ただしプログラミングにおける関数は皆さんが見慣れた数学よりも複雑なことをすることができます。
例えば、以下のように数値ではない値が結果となったり
function f(x) {
return "The value of x is " + x
}
何もしなかったり、
function f (x) { // 普通はこのような関数は作りません
}
if文で条件分岐したり
function f (x) {
if (x % 2 === 0) {
return "even"
} else {
return "odd"
}
}
for文で繰り返し処理したり
function f (x) { // 0 ~ xまでの合計を求める関数
let result = 0;
for (let i = 0; i <= x; i++) {
result = result + i
}
return result
}
といった感じで、言ってしまえば基本的になんでもできます。
「関数はなんのためにある?」
関数を使うことによる利点のうち最初に実感できるものは以下の二つだと思います。
1. 処理に名前をつけることができる
早速ですが質問です。以下の二つのプログラムどちらがわかりやすいでしょうか?
const point1 = { x: 10, y: -5 }
const point2 = { x: 3, y: 1 }
const dx = point1.x - point2.x
const dy = point1.y - point2.y
const dist = Math.sqrt(dx ** 2 + dy ** 2) // Math.sqrtは √ の計算
function distance(point1, point2) {
const dx = point1.x - point2.x
const dy = point1.y - point2.y
return Math.sqrt(dx ** 2 + dy ** 2) // Math.sqrtは √ の計算
}
const point1 = { x: 10, y: -5 }
const point2 = { x: 3, y: 1 }
const dist = distance(point1, point2)
これらはどちらも2つの点の距離を計算するプログラムです。違いとして、上は関数を用いておらず下は関数を用いています。 その違いによって読む時にこのような違いが現れます。
- 上の場合、全てのプログラムを読んだ上で何をしているのかを理解する必要があります。
- 下の場合、関数名が
distance
であり二つの引数を受け取ることから、その関数が二つの点の距離を計算するものであると「予想」ができます。
そして結果としてその「予想」は正しいです。
今回は2点の距離を求めるだけなのでどちらも問題なく読めると思います。 ですがこれがマクローリン展開を用いたsin関数の計算のような、ある程度複雑な計算だとどうでしょうか...? 名前が無いと何をしているかわからなくなることは想像に難くありません。
コラム:マクローリン展開を用いたsin関数の定義と実装
- マクローリン展開を用いたsinの計算
- 実装(ChatGPTくんに書いてもらった👅)
function sin(x) {
let result = 0
for (let k = 0; k <= 3; i++) {
const sign = ((-1) ** i)
const numerator = x ** (2 * i + 1)
const denominator = factorial(2 * k + 1)
const result += sign * numerator / denominator
}
}
function factorial(x) {
if (x === 1) {
return 1
} else {
return x * factorial(x - 1)
}
}
基本的にはMath.sin
を用いるため自作することはないし上のsin関数はxの値によっては安全な計算ができない可能性があるが、ここでは複雑な関数の例として挙げてみた。
2. プログラムを細かく切り分けることができる。
先程のと若干被りますが、関数を使うとプログラムを小さな単位で切り分けて名前をつけることができます。
すると例えば100行のプログラムを、10行の関数10個とそれらを使った10行のプログラムにすることができるので人間の記憶力に優しいものになります。
関数の書き方
JavaScript関数には普通の関数、無名関数、アロー関数があります。
どれでも書けるようになっておくと便利です。
普通の関数
function 関数名(引数名) {
// 処理内容
}
// 引数はなくてもよい
function 関数名() {
// 処理内容
}
// 逆に複数にする時はこの様に書く
// これは二つだが、同様にして , で区切ると3個、4個...と増やせる
function 関数名(引数名1, 引数名2) {
// 処理内容
}
呼び出し
関数名(引数)
例
以下は与えられた引数が偶数かどうかを判定する関数。
function checkIsEven1(n) {
if (n % 2 === 0) {
console.log(n + " is even.")
} else {
console.log(n + " is not even.")
}
}
checkIsEven1(4)
checkIsEven1(5)
無名関数
その名の通り名前がない関数。 「名前がないのでは意味がないじゃん」と思うかもしれないが、「名前が要らない場合」というのが存在する。
また、無名関数を変数に代入することによって無名関数に名前をつけることもできる。 「なんでそんな回りくどいことを?」 と思うだろうが、好みとか色々あるんです。
書き方
// このままでは名前がないので呼び出せない
function (引数名) {
// 処理内容
}
// 変数に代入することもできる
const 関数名 = function (引数名) {
// 処理内容
}
例
以下は与えられた引数が偶数かどうかを判定する関数。
const checkIsEven2 = function (n) {
if (n % 2 === 0) {
console.log(n + " is even.")
} else {
console.log(n + " is not even.")
}
}
checkIsEven2(4)
checkIsEven2(5)
アロー関数
これまでのとは全く違う関数の書き方。これも無名関数と同じく名前がない。
アロー関数も同じく変数に代入することができる。
書き方
// このままでは名前がないので呼び出せない
(引数名) => {
// 処理内容
}
// 変数に代入することもできる
const 関数名 = (引数名) => {
// 処理内容
}
例
以下は与えられた引数が偶数かどうかを判定する関数。
const checkIsEven3 = (n) => {
if (n % 2 === 0) {
console.log(n + " is even.")
} else {
console.log(n + " is not even.")
}
}
checkIsEven3(4)
checkIsEven3(5)
return文
先ほどから関数の例で出てきていたヤツ。 これを使うことで関数の結果を返すことができる。
またreturn
は関数の「結果」を返すので、もちろん関数の処理はreturn
が実行された時点で終了する。
function f(x) {
return x ** 2 + x * 2 + 1
}
console.log(f(6))
return
を使わない場合、関数は結果を返さない。
function f(x) {
x ** 2 + x * 2 + 1
}
console.log(f(6))
また return
の後に何も書かなければ関数は結果を返さずに終了させることができる。
function f(x) {
return // ここでこの関数は終了するし、なんの値も返さない。
x ** 2 + x * 2 + 1 // returnで終了するのでここの計算はされない
}
演習
関数を使ってみよう。
余裕のある方は、いろいろな関数の書き方でやってみよう。
問題1 min
- 問題
- 解答例1
- 回答例2
引数に数値を二つ取り、その二つのうち小さい方を返す関数を作成しなさい。
function min(a, b) {
if (a < b) {
return a;
} else {
return b;
}
}
const min = (a, b) => a < b ? a : b
これについて気になる人は聞いてみよう!
問題2 helloWorldNTimes
- 問題
- 解答例1
- 回答例2
引数に正の整数値を取り、その回数だけHello World!
と出力する関数を作成しなさい。
function helloWorldNTimes(n) {
for (let i = 0; i < n; i++) {
console.log("Hello World!")
}
}
const helloWorldNTimes = (n) => {
new Array(n).fill(0).forEach(() => {
console.log("Hello World!")
})
}
これについて気になる人は聞いてみよう!
問題3 arrayMin
- 問題
- 解答例1
- 回答例2
引数に数値の配列を取り、配列内の最小の数値を返す関数を作成しなさい。
配列の長さは、配列.length
で取得できる。
function arrayMin(a) {
let min = a[0]
for (let i = 1; i < a.length; i++) {
if (a[i] < min) {
min = a[i]
}
}
return min;
}
const arrayMin = (a) => a.reduce((a, b) => a < b ? a : b, a[0])
これについて気になる人は聞いてみよう!