JavaScript関数の基礎構文と種類の使い方解説 | 初心者向けJavaScript学習ガイド
この記事では、初心者向けにJavaScriptの関数・関数式およびアロー関数の基礎構文について学習します。
JavaScriptで利用できる関数にはさまざまな種類があります。
全てをここで紹介は難しいですが、ほとんどの関数動作を学んでいきましょう。
関数は、特定のタスクを実行するコードのブロックとなります。
何かしらの図などの機能を作成して色を付けたりするプログラムを作成する必要があるとします。
まず問題を解決するために2つの関数を作成できます。
図を描く関数と図に色を付ける関数
1つの複雑な問題を小さな機能によって分割すると、プログラムが理解しやすくなり、再利用しやすくなります。
メイン機能プログラムとは別に保持および保守できます。
関数はより移植性が高く、デバッグが容易で再利用可能なコードパッケージを作成する方法を提供します。
関数の利点
・ コードの再利用性(保守)
一度作成された関数は何度でも使用できるため、関数内で行われた変更は、すべての場所で自動的に実装されます。
コーディングの節約にもなります。
・ エラーの修正
プログラムを関数に分割するとエラーが発生した際、エラーの原因となった関数とその場所が明確にわかります。
ですのでエラーの修正がはるかに簡単となります。
・ コンパクトになる
関数を作成するとプログラムがコンパクトになります、一般的なタスクを実行するために毎回多くのコード行を記述していく必要はありません。
本日は通常の関数だけでなくJavaScriptのES6 アロー関数についてもすべて学びます。
最新のES6のアロー構文の使用方法と、コードでアロー関数を使用するときに注意するべき一般的な間違いのいくつか、そして通常の関数との違いを示します。
それらがどのように機能するかを見ていきましょう。
関数の宣言と呼び出し
通常の関数を宣言するための構文は以下の通りとなります。
function functionName () { // 関数の内部、実行するコード }
JavaScriptの関数は0個以上の引数を取る事できます。
カンマ繋ぎでスペースを空けて記述します。
function functionName (test1, test2, test3) { // 関数の内部、実行するコード }
まずは引数なしの簡単な例を見てみましょう。
関数の宣言は、「function」キーワードで始まり作成する関数の名前
、括弧()
、最後に関数のコードを中括弧{ }
で囲みます。
関数の名前を付ける基本的なルールは、変数に名前を付ける時とほぼ同様で似ております。
変数の時と同様に、分かりやすい名前を書く事をお勧め致します。
そして関数の本体は内側{ // 関数の内部、実行するコード}
に記述されます。
function greet() { alert("Hi, Hello!!"); }
上記のプログラムでは、greet()
という名前の関数を宣言しました。
その宣言した関数を使用するには、それを呼び出す必要があります、すごく簡単です。
function greet() { alert("Hi, Hello!!"); } greet(); // 関数の呼び出し
名前の後に括弧()
を入力することにより、どこからでも呼び出すことが可能となります。
関数リターン(戻り値)
returnを使用し、値を関数呼び出しに返すことができます。
値は配列やオブジェクトなど、任意の型にすることが可能です。
returnは関数処理が終了した事を示します。
前述した通りJavaScript関数には0個以上の引数を取る事が可能です。
引数とは関数を呼び出す際に渡す「値」です。
その渡された値に対し処理を行い、処理された結果を返すという事になります。
例えば、引数の値を数値にしその値の処理を行い計算をします。
計算された値の結果を返します。
返ってきた値を「戻り値」と言います。
単純な足し算でみてみましよう。
function getNum(num1, num2) { let total = num1 + num2; return total; } console.log(getNum(1, 2)); // 3
上記のプログラムでは、数値の合計の結果はreturnを使用する関数によって返されます。
そして、その値の結果は変数に保存されています。
function greet(foo1, foo2) { let total = foo1 + foo2; return total; } console.log(greet("Hi,", "Hello!!")); // Hi, Hello!!
注意点は、何も返されない場合の関数はundefinedの値を返します。
関数は、それぞれ各小さなタスクが関数によって分割されるため、プログラムを簡単にします。
そして関数はコードの再利用を可能にし、一度宣言して複数回使用することができます。
関数を別の変数として格納しコピーする事が可能です。
数値の計算をする関数を別の変数へコピーします。
function greet(foo1, foo2) { let total = foo1 * foo2; return total; } let func = greet; // copy console.log(func(6, 6)); //36 console.log(greet(6, 6)); //36
以下は文字列になります。
function greet(foo1, foo2) { let total = foo1 + foo2; return total; } let func = greet; // copy console.log(func("Hi,", "Hello!!")); //Hi, Hello console.log(greet("Hi,", "Hello!!")); //Hi, Hello
greet
関数をfunc
という変数にコピーします。
出力は同じ結果となります、つまり両方として呼び出しが可能です。
関数式(無名関数)
前述の関数を作成するために使用した構文は、関数宣言と呼ばれます。
関数には、別の構文があります。
関数が変数に格納されると、その変数を関数として使用できます。
JavaScriptでは関数を「式」として定義が可能という事です。
let x = function(num) { return num * num }; console.log(x(2)); // 4 let y = x(3); console.log(y); // 9
変数x
に関数を格納しております。
これで関数は式として扱われる事になります。
関数式では名前を省略できます、名前を省略すると、その関数には名前が無い事になります。
その場合での構文では無名関数
と言います。
無名関数では、呼び出しは関数自体ではなく変数名を使用して呼び出されるのでご注意下さい。
関数宣言と関数式は非常に似ている構文ですが、実行時の評価は異なります。特に初心者にとっては混乱しやすいかもしれません。
以下のコードを見て、それぞれの実行結果と挙動の違いを比較しましょう。
declaration(); // 実行される function declaration() { console.log("関数宣言"); } expression(); // TypeError let expression = function() { console.log("関数式"); };
関数式を呼び出すときに例外のTypeError
が発生しましたが、関数宣言は正常に実行されました。
これは、プログラムが評価される際に関数宣言が現在のスコープの最上位に引き上げられるというJavaScriptの特性によるものです。
言い換えると、関数宣言はプログラムのどの部分よりも前に呼び出すことができます。
一方、関数式では変数に関数が割り当てられるまで評価されません。
そのため、関数式を呼び出した時点では関数がまだ定義されていないため、TypeError
がスローされます。
関数式では、実行時に関数が作成され、それ以降に使用できるようになります。
以下のコードを見て、関数式が定義される前に呼び出すとどうなるかをもう一度、確認しましょう。
expression(); // TypeError let expression = function() { console.log("関数式"); }; expression(); // 正常に実行される
関数式が定義される前に呼び出した場合、再びTypeError
が発生します。
しかし、関数式が定義された後に呼び出すと、正常に実行されます。
以上のように、関数宣言と関数式では挙動が異なることがわかります。
これらの違いを理解するには、スコープ(または可変スコープ)の概念を学ぶことが重要です。
スコープは以前に記事にしましたので以下を参照下さい。
ES6 アロー関数
アロー関数は、ES6またはECMAScript 2015の仕様で導入された比較的新しい機能です。アロー関数は常に式となり、その表記は矢印のような記号であり、その形状が弓矢の矢に似ていることからアロー関数と呼ばれます。
アロー関数は通常の関数式の代替として導入されました。
変数や定数に格納され、return文や中括弧{}を省略してコンパクトに書くことができます。
以下はアロー関数を使った例です。
const getNum = (num1, num2) => num1 + num2; console.log("計算結果: " + getNum(1, 1)); // 出力: 計算結果: 2
この例では、functionキーワードを使った場合と比べてもアロー関数の方がシンプルで、1行で簡潔に書くことができます。
アロー関数では、return文や中括弧{ }が省略されており、これを「暗黙のreturn」と呼ぶこともあります。
ただし、暗黙のreturnはコードの可読性に注意が必要です。
複数の式や複雑な関数の場合、またはオブジェクトを返す必要がある場合は、通常の関数と同様に中括弧{ }で囲み、return文を使って値を返すことができます。
また、アロー関数は、より短く、より簡潔なコードを書くことを目的としています。
引数が1つしかない場合は、引数を囲む括弧()を省略してさらに短く書くこともできます。
let double = n => n * 2; console.log(double(3)); // 出力: 6
引数がない場合は、空の括弧( )
を書く必要があります。
let sayHello = () => "こんにちは"; console.log(sayHello()); // 出力: こんにちは
例えば、動的にアロー関数を作成する場合は、以下のように書くことができます。
// ユーザーに年齢を尋ね、デフォルト値として20を指定する let age = prompt("あなたの年齢は何歳ですか?", 20); // 年齢に応じて適切な挨拶を表示するための関数を定義する let greet = (age < 19) ? // ageが19未満かどうかをチェックする条件演算子 () => alert('こんにちは!') : // ageが19未満の場合に実行されるアロー関数 () => alert("やあ"); // ageが19以上の場合に実行されるアロー関数 greet(); // 適切な挨拶を表示する関数を実行する
上記のコードでは、アロー関数を使用して条件に基づいて適切な挨拶を表示するための関数を定義しています。
最初に、prompt()
関数を使用してユーザーに年齢を尋ねます。デフォルトの値として20
が提供されています。
次に、条件演算子(三項演算子)を使用して、age
が19未満かどうかをチェックします。もし19未満であれば、アロー関数() => alert('こんにちは!')
が変数greet
に代入されます。
そうでなければ、アロー関数() => alert("やあ")
が代入されます。
最後に、greet()
を実行することで適切な挨拶が表示されます。
greet()
は条件に基づいて、age
が19未満であれば「こんにちは!」、19以上であれば「やあ」というアラートを表示します。
このように、アロー関数は、() =>
のような構文で定義されます。
( )
内に引数を指定し、=>
の後に関数本体を記述します。アロー関数は無名関数として使われることが多く、変数に代入して使用することが一般的です。
また、アロー関数は、外部のスコープ(この場合はgreet関数の外側)から変数や引数をキャプチャできます。このため、条件演算子内のアロー関数は、外側のage
変数にアクセスして条件を判断することができます。
最初は慣れるまで読みにくいかもしれませんが、書いているうちにすぐに慣れてきます。
現代のJavaScriptでは、ES6の機能を活用したコーディングが主流となっています。ES6は、JavaScriptのバージョンとして2015年に導入されたECMAScriptの仕様です。
ES6では、アロー関数の他にも多くの機能が追加されました。例えば、let
やconst
によるブロックスコープの導入、テンプレートリテラルによる文字列の簡潔な表現、分割代入によるデータの抽出、クラス構文の追加などがあります。
これらの機能は、可読性の向上や効率的なコーディングを可能にするため、多くの開発者によって積極的に活用されています。また、ES6の機能はブラウザやNode.jsなどの実行環境で広くサポートされており、モダンなJavaScriptアプリケーションの開発に欠かせないものとなっています。
ES6以降の新しい機能や文法を使ったコードは、より短く、より読みやすくなる傾向があります。また、新しい機能は開発者の生産性向上にも寄与しています。
したがって、現代のJavaScript開発では、ES6の機能を積極的に活用し、より洗練されたコードを書くことが求められています。
関数オブジェクト
関数を使用してオブジェクトを返すには、様々な方法がございます。
まずは、通常の関数の例です
function returnObj() { let myObj = { "name": "Taro", "age": 30, "city": "TOKYO" }; return myObj; } let obj = returnObj(); console.log(obj);
このコードでは、returnObj
という名前の通常の関数を定義しています。関数内でmyObj
というオブジェクトを作成し、そのオブジェクトをreturn
キーワードを使って関数の呼び出し元に返しています。関数を呼び出し、返されたオブジェクトを変数obj
に代入し、最後にその内容をコンソールに出力しています。
次に、無名関数の例です。
const obj = function() { let myObj = { "name": "Taro", "age": 30, "city": "TOKYO" }; return myObj; }; console.log(obj());
このコードでは、無名関数(関数式)を定義しています。
無名関数は変数obj
に代入され、関数内でmyObj
というオブジェクトを作成し、そのオブジェクトをreturn
キーワードを使って関数の呼び出し元に返しています。関数を呼び出し、返されたオブジェクトをコンソールに出力しています。
最後に、アロー関数の例です。
const obj = {}; const myObj = obj => { obj.name = "Taro"; obj.age = 30; obj.city = "TOKYO"; return obj; }; console.log(myObj(obj));
このコードでは、変数obj
に空のオブジェクトが代入されています。
アロー関数myObj
は引数としてオブジェクトobj
を受け取り、そのプロパティに名前、年齢、都市の情報を追加しています。
そして、追加されたオブジェクトをreturn
キーワードを使って関数の呼び出し元に返しています。関数を呼び出し、返されたオブジェクトをコンソールに出力しています。
即時関数
即時関数は、定義された時点で自動的に実行される関数であり、手動で呼び出す必要がありません。
即時関数を作成するためには、2つの構文があります。
最初の構文は次のようになります。
(function () { // 内部の処理 }());
2番目の構文は次のようになります。
(() => { // 内部の処理 })();
2番目の構文は一般的であり、さらにアロー関数を使用することもできます。
次に、1番目の構文の即時関数の例を示します。
(function thisIsANamedIIFE() { alert("名前付き即時関数"); })(); let foo = function myself(greetings){ alert('Hello!!!'); // 呼び出される if (greetings === true) myself(false); }; foo(true); // 呼び出される // 出力: Hello!!! // 出力: Hello!!!
ただし、最初の構文ではアロー関数を使用しようとするとエラーが発生します。
次に、式としての即時関数の例を示します。この場合、関数に直接引数を渡して実行します。
let x = (function (a, b) { let result = a + b; return result; })(1, 2); alert(x); // 出力: 3
(function (greetings) { alert('Hello!!!'); // 呼び出される if (greetings === true) arguments.callee(false); })(true);
アロー関数を使用した即時関数の例では、名前付き関数は定義できないことに注意してください。
(() => { alert('アロー関数の即時関数です'); // 実行される })(); ((foo, num) => { let x = foo + num; alert(x); })(1, 1); // 出力: 2
以上が即時関数に関する説明と例です。
関数配列
アロー関数は、JavaScriptの配列メソッドであるmap、reduce、filterなどでよく使われます。これらの配列メソッドを使うことで、わずかなコードで配列の変換が行えます。
const myArray = [1, 2, 3, 4].map(num => num * 2); console.log(myArray); // 出力: [2, 4, 6, 8]
上記のコードでは、[1, 2, 3, 4]
という配列の各要素に対して、アロー関数を使用して変換を行っています。
mapメソッドは、元の配列の要素を変換して新しい配列を作成するため、[1, 2, 3, 4]
の各要素にアロー関数が適用され、それぞれの要素が2倍された結果の配列 [2, 4, 6, 8]
が生成されます。
最後の行では、console.log
を使って変換された配列を表示しています。
上記のように、アロー関数を使用することでコードを短く保ちながら、シンプルで明快な記述が可能となります。
しかし、アロー関数は、通常の関数と比較して、this
の挙動が異なります。
アロー関数内でのthis
は、その関数が定義されたコンテキスト(外部のスコープ)に束縛されます。一方、通常の関数では、this
の値は実行時によって決まるため、注意が必要です。
この、this
のトピックについては、以下で詳しく解説していますので参照ください。
最後に
関数がどのように作成されても、関数は値です。
JavaScriptでは値として扱います、そしてコードの任意の場所で割り当て、コピーまたは宣言できます。
関数式では、実行フローが関数式に到達したときに作成され実行されます。
関数宣言では、コードブロックが実行される前に処理され、それらはブロック内のどこにでも表示されます。
アロー関数は、配列操作関数およびコールバック関数に最も最適となっております。
関数が式として扱われた場合それは、全て関数式(無名関数)となります。
本日は以上となります。
最後まで読んで頂きありがとうございます。
この記事が役に立ったら、ブックマークと共有をしていただけると幸いです。