Search

検索したいワードを入力してください

2019年04月10日

JavaScriptで関数を使う方法|開発の基本をマスター

関数はJavaScriptの中で最もよく使う機能の1つです。その種類もたくさんあります。この記事では、function文や無名関数などの関数の基本的な使い方からアロー関数やクロージャなどの特殊な使い方まで、コード例を用いて幅広く説明しています。

関数とは

一次関数や二次関数など、「関数」という言葉に聞き覚えのある方は多いのではないでしょうか。xやyを利用して、直線や放物線などの図やグラフの特徴を表すために使われたり、未知の数を求めるために利用されたりします。

言葉としては親近感のある「関数」という言葉ですが、関数とはどういう意味か聞かれると答えに窮する方もいるでしょう。ここではシンプルに、関数とはあるインプットに対して決まった処理を行い、実行結果をアウトプットするものと定義づけられます。

義務教育や高等教育の過程で学習してきた関数にはグラフの特徴を表すことが主の関数もありますが、プログラミングでは基本的に上記で記したようにある値を返すための機能ぐらいの意味になります。

関数とプログラミングはかなり密接な関係にあると言えます。プログラミング言語の中ではその基本構造に関数を中心に据えた言語もあり、そういったプログラミング言語のことを関数型プログラミング言語と総称したりします。

一方、現在主流のプログラミング言語の構造はオブジェクト指向プログラミングと呼ばれるもので、ここで学習するJavaScriptやPython、Java、Rubyなどの現在主流となるプログラミング言語の多くがこのオブジェクト指向プログラミングに位置づけられます。

しかしこれらオブジェクト指向プログラミングでも関数型プログラミングの利点は取り入れられています。そのため、大体のオブジェクト指向プログラミングでは、自由に自作関数を作成できるようになっています。

このように関数とプログラミング言語は切っても切れない関係にあります。今回はJavaScriptで関数をどのように扱う、基本的なことから特殊な関数まで幅広く紹介していきます。コード例だけでなく自作関数も作ってみて、しっかりと理解していきましょう。

メソッド関数の違い

オブジェクト指向プログラミングでは関数と似た言葉に「メソッド」という言葉があります。機能的にも関数とメソッドは似ていますが、メソッドとはオブジェクト指向プログラミングの文脈で使われる言葉で、データを抽象化した「オブジェクト」の振る舞い、処理を表すものです。

関数は定義しさえすれば、自由に使えることができますが、メソッドはオブジェクトに紐づいたもので、対象とするオブジェクトでしか実行できません。

関数を定義する

JavaScriptで関数を定義する方法は複数ありますが、最も利用される方法は関数の宣言を行うfunction文と関数式で定義を行ういわゆる無名関数と言われる方法です。関数式の宣言では、関数としての体裁がきちっと整えられるため、利用シーンが多い関数を定義するときに使われます。一方で、無名関数はその名のとおり特定の関数名をつけずに定義することができる関数のことで、一時的、即応的な場面で関数を必要とするときに使われる方法です。この2つの関数を定義する方法を具体的にみていきましょう。

関数の宣言(function文)

まずは関数の宣言を行うfunction文です。関数の宣言を行うfunctions文はJavaScriptで関数を生成するときに最も一般的に使われる方法で、関数内の実行コードを色々と設定することでで自身が求める結果を返す関数を簡単に作ることができます。JavaScriptのfunction文の基本構造をみてみましょう。

// 関数を定義する(1) - 関数の宣言
function function_name(args) {
// 実行コード
}


argsとは引数のことで、引数をfunction_nameに任意の名称を入れることで独自の関数名をつけることができます。JavaScriptで最も基本となるfunction文の基本構造がわかったところで、次はコード例をみてみましょう。

// 関数を定義する① - 関数の宣言
function numHandler(num) {
var sqrt = Math.sqrt(num);
var square = num * num;
console.log('平方数: '+sqrt);
console.log('二乗 : '+square);
}

numHandler(121);

// 戻り値
平方数: 11
二乗 : 14641


このコード例は、平方数と二乗の両方の結果を表す関数です。関数名を使って呼び出すと、関数内に記述した実行コードに沿って、処理されていることがわかります。

関数式による関数定義(無名関数)

次はJavaScriptで関数を作る2つ目の方法である関数式をみていきましょう。関数式と呼ばれるように、この方法では変数に関数の機能を持たせてしまいます。まずは関数式の基本構造をみてみましょう。

// 関数を定義する(2) - 関数式
// 無名関数型
var 変数 = function(args) {
// 実行内容
}


関数の宣言と似てはいますが、関数の宣言をするのではなく変数に関数の機能を格納していることがわかります。関数の名前をつけないことからこの関数のことを「無名関数」と呼びます。

しかし、実際はfunctionの後に関数名をつけることはできますが、関数機能自体は変数に格納されてしまうため、関数名を使って関数を呼び出すことができないため、特に意味はありません。それでは無名関数のコード例を見てみましょう。

// 無名関数
var tryNumHandler = function(num) {
var sqrt = Math.sqrt(num);
var square = num * num;
console.log('平方数: '+sqrt);
console.log('二乗 : '+square);
}

tryNumHandler(121);

// 戻り値
平方数: 11
二乗 : 14641


関数式で作ったこの関数は、function文で作成したコード例と同じ機能を持ちます。さきほどのfunction文のコードと見比べると、function文との共通点と違いがわかります。

最初の書き方と関数へのアクセスの仕方だけが少し異なる程度であり、このようにJavaScriptでは非常に簡単に関数を作ることができます。ご自身でもオリジナル関数の作成にチャレンジしてみてください。

アロー関数でさらにシンプルに

アロー関数はJavaScriptの最新版のバージョンであるES6で追加された機能で、非常に簡潔に関数を実装できます。上記で、JavaScriptではfunction文と関数式の2つの方法で関数が作れることを見てきました。アロー関数は関数式のように記述できますが、関数式とは違い1文で記述できる点でさらに簡潔に関数を作れる機能であると言えます。まずは基本構造を見てみましょう。

// アロー関数
var fanction_name = (args1, arg2, ...) => { 実行内容 }


上記の基本構造を見ると、アロー関数の構造が非常に簡単であることがわかります。また、引数が1つの場合は引数の丸括弧を省略できます。またconstやletで定義する変数でも利用することができます。それではコード例を見てみましょう。

var numHandler = arg1 => arg1**2;
numHandler(3)

// 戻り値
9


上記は引数が一つの場合のアロー関数の使い方を例示したコードです。引数が1つの場合はこのように丸括弧を記載しなくても大丈夫です。また、実行処理が複数に分かれないのであれば、矢印後の関数の実行内容の記述に波括弧はいりません。もう一つアロー関数の例を見てみましょう。

var testFunc = (arg1, arg2) => { console.log('arg1: '+arg1+', arg2: '+arg2); }
testFunc('first argument', 'second argument')

// 戻り値
arg1: first argument, arg2: second argument

このコード例では、引数が2つあるので、丸括弧を記載しています。この2つのコード例からアロー関数が非常に簡単に使えるJavaScriptの機能であることがわかります。簡潔にコードを記載したいとき、一時的に簡潔な関数を使いたいときに非常に便利に使うことができる機能ですので、しっかり把握していきましょう。

JavaScriptで関数を呼び出す方法

今までJavaScriptの関数の作り方をみてきました。次は、作った関数の呼び出し方をみてみましょう。JavaScriptでの関数の呼び出し方は他のプログラミング言語と同じで非常に簡単で、関数名とそのあとに丸括弧で引数を指定してあげるだけです。先ほど自作した関数を使って確認してみましょう。

// 関数を定義する① - 関数の宣言
function numHandler(num) {
var sqrt = Math.sqrt(num);
var square = num * num;
console.log('平方数: '+sqrt);
console.log('二乗 : '+square);
}

numHandler(121);

// 戻り値
平方数: 11
二乗 : 14641


numHandlerという関数名に引数121を渡して関数を呼び出しているのがわかります。続いては、無名関数の場合もみてみましょう。

// 無名関数
var tryNumHandler = function(num) {
var sqrt = Math.sqrt(num);
var square = num * num;
console.log('平方数: '+sqrt);
console.log('二乗 : '+square);
}

tryNumHandler(121);

// 戻り値
平方数: 11
二乗 : 14641


無名関数では、関数名を特につけないため、変数名とそれに続いて丸括弧に引数を指定することで呼び出すことができます。このようにJavaScriptでは関数を定義してしまえば、非常に簡潔に関数を呼び出すことができます。

関数の引数とは

関数では引数を設定することで関数で処理する値を自由に決めることがでいます。引数を使うことで、関数の使い勝手や柔軟性が上がると言えます。早速コード例をみてみましょう。

function numHandler(num) {
var sqrt = Math.sqrt(num);
var square = num * num;
console.log('平方数: '+sqrt);
console.log('二乗 : '+square);
}

numHandler(121);

// 戻り値
平方数: 11
二乗 : 14641


ここでは引数に121を設定しています。この値を変えることで、違う結果を出すことができます。引数によって、関数の汎用性が高くなっていることがわかります。

returnを使って関数の戻り値を指定する

JavaScriptでは、return文を使うことで関数の戻り値を指定することができます。これは引数同様、関数の基本的な機能になります。早速コード例をみてみましょう。

// 関数の戻り値 - 基本
function testFunction(arg1) {
return arg1 ** 2;
}
var test = testFunction(11)
test

// 戻り値
121


testFunctionという自作関数がreturn文で引数を2乗した値を値を返し、それをtestという変数に格納されていることがわかります。このようにreturn文で値を返すことで、その後のプログラムで関数の実行結果を柔軟に使うことができるようになります。

関数を変数のように使って条件分岐をしてみる

関数ではif文を活用することで条件を分岐させることもできます。こちらも基本構造は関数と同じになりますので、早速コード例をみて確認してみましょう。

// 関数の戻り値 - 応用
function testFunction(arg1, arg2) {
var arg1Sqrt = arg1**2;
if (arg1Sqrt <= 10000) {
return arg2;
} else {
return arg1;
}
}
testFunction(101, 1)

// 戻り値
101


関数の内部でif文による条件分岐が行われており、合致する値が返されていることがわかります。関数では、実行処理コードでJavaScriptで使える色々な機能が使え、多彩な関数を作り出すことができます。

再帰関数とは

JavaScriptの再帰関数とは、関数内でその関数自体を呼び出す、いわば自己言及する関数のことです。特定の条件下では同じ処理を継続したい場合などに便利ですが、条件の指定の仕方次第では無限ループになるため、注意が必要です。早速コード例を見てみましょう。

function sqrtFunction(x) {
if(x > 1000) {
return;
} else {
console.log(x);
x = x*2 ;
return sqrtFunction(x); //自己言及している
};
}

sqrtFunction(2);

// 戻り値
2
4
8
16
32
64
128
256
512

xの値が1000を超えるまで関数自身を呼び出していることがわかります。一方で、xの値をどんどん更新できるため、通常のforループよりもわかりやすい実装になっています。

関数のスコープとは

関数では、どのレベルの変数を使えるかに関する範囲が決められており、スコープと言われます。スコープのルールは非常に簡単で、関数内から関数外の変数は参照でき、反対に関数外からは関数内の変数を参照することはできません。言葉だとわかりにくいですが、コード例を見るとわかりやすいので、早速コード例をみてみましょう。

var testGlobalVar = 'global variation'
function testScope() {
var testLocalVar = 'function variation';
console.log('testGlobalVar(from function): '+testGlobalVar);
console.log('testLocalVar(from function): '+testLocalVar);
}

testScope(10)
console.log('')
console.log('testGlobalVar(from function): '+testGlobalVar)
console.log(testLocalVar)

// testGlobalVar -> どちらからもアクセスできている
// testLocalVar -> 関数内でしかアクセスできていない

// 戻り値
testGlobalVar(from function): global variation
testLocalVar(from function): function variation

testGlobalVar(from function): global variation
//console.log(testLocalVar) -> エラー

コード例を見ると、関数外にある変数、いわゆるグローバル変数は関数の外からも内からも両方からアクセスできることがわかります。

一方で、関数内の変数は関数の中でしかアクセスできません。関数のスコープは関数を作るときの重要なポイントになるため、それぞれ対象となるスコープをしっかり把握しましょう。

入れ子関数でより複雑な処理をする

JavaScriptの関数では、関数の中に関数を定義し、入れ子になった関数を作ることができます。入れ子関数は複雑な関数にはなりますが、重層的な関数を作り出すのに役立ちます。こちらも百聞は一見にしかず、ですので、早速コード例をみてみましょう。

//入れ子関数
function testFuncA(arg) {
var testNum = arg;
function testFuncB() {
testNum *= 3.1415;
return testNum
}
return testFuncB()
}
testFuncA(2)

// 戻り値
6.283


関数Aの中に関数Bが作られており、関数Aを実行すると、その引数が関数Aの中で関数Bに渡され、その実行結果が最終的に関数Aの実行結果になっていることがわかります。このようにJavaScriptでは、関数の中に関数を定義した入れ子関数を作ることができます。

クロージャとは

入れ子関数の中で最も重要な機能の一つがクロージャです。クロージャは「独立した変数を参照する関数」と公式には定義されていますが、よりわかりやすく言い換えると「状態を保持しておく関数」と言えます。

通常の関数では、変数の値は、設定された値を参照するだけで、変更された値を覚えておくことはありません。しかし、クロージャでは状態を保持しておくことができるため、更新された変数を記憶しておくことができます。早速コード例をみてみましょう。

// クロージャ
function FibonacciNumber() {
var returnValue = 0;
var number = 0;
var preNumber = 0;
function Fibonacci() {
if (number == 0) {
number++
returnValue = number;
} else if (number == 1) {
returnValue = preNumber+number;
preNumber = number;
number = returnValue;
} else {
returnValue = preNumber + number;
preNumber = number;
number = returnValue;
}
return returnValue;
}
return Fibonacci;
}
var value = FibonacciNumber();

for (i=0; i < 20; i++) {
console.log(value());
}

// 戻り値
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765

これはフィボナッチ数列という有名な数列を実装したコードです。フィボナッチ数列は、2つ前と1つ前の値を足し合わせて数列を作ります。この関数では外側にfibonacciNumber、内側にfibonacciという関数が存在しています。

そして内側のfibonacci関数では、returnValue、number、preNumberという3つの変数を参照しています。fibonacciが独立した基本的な関数の場合、これら変数の値は実行されるごとに初期化されてしまいますが、この入れ子関数の構造、いわゆるクロージャでは、初期化されず値がどんどん更新されていきます。

このように状態を保持する関数構造がクロージャです。

JavaScriptの関数のまとめ

今回は、JavaScriptの関数についてまとめましたが、いかがでしたでしょうか。関数は利用シーンが非常に多く、とても役に立ちます

一方で基本的な使い方からクロージャやアロー関数など特殊な使い方もたくさんあります。JavaScriptの色々な関数を理解し、どんどん使っていきましょう。

多くの人がプログラミングを諦めてしまう理由をご存知ですか?



近年プログラミングを勉強する人が増えています。

プログラミング学習者の多くは独学から取り組もうとしますが、だいたい80%ほどは3ヶ月も続かずに諦めてしまいます。早い人は1日目で。

多くの人がプログラミングを独学しようとして諦める理由は、次の3つ。
●モチベーションが維持できない
●エラーの原因・解決方法が分からない
●どう学習すればよいか分からない

TechBoostというプログラミングスクールでは、みんなと一緒にプログラミングをするのでモチベーションの維持ができ、分からないことがあればマンツーマンで教えてくれ、徹底的に研究された初心者向けの教材が揃っています。

TechBoostを卒業後、実際にエンジニアとして転職した方もいるほど。

本気でプログラミングを学びたい方は、一度無料のカウンセリングでご相談ください。プログラミングを嫌いになる前に。

tech boost卒業生インタビュー

tech boostの卒業生の声を聞きました。あなたがプログラミングを学びたい理由を、一度考えてみてください。
営業→Javaエンジニア→Rubyエンジニアと転向し、第一志望のFinTech企業で働く山下さん
元営業、ビジネスのわかるエンジニアを目指す菅原さん
サンフランシスコに交換留学し、シリコンバレーのVCでインターン中の梅本さん
予備校の営業から半年でエンジニア転職を果たした小田島さん

tech boostの口コミ



Related