JavaScript の関数定義
1. 関数定義と関数宣言の違い
「関数定義(Function Definition)」は関数を定義すること全般を指す一般的な用語です。
一方、「関数宣言(Function Declaration)」は関数を定義するための特定の具体的手法の一つを指します。
関数定義の例には以下のものが含まれます:
- 関数宣言 (Function declarations)
- 関数式 (Function expressions)
- アロー関数 (Arrow functions)
1.1 関数定義の例
// 関数宣言 (Function Declaration)
function myFunction(x, y) {
return x * y;
}
// 関数式:名前付き (Named Function Expression)
const myFunction = function name(x, y) {
return x * y;
};
// 関数式:匿名/無名 (Anonymous Function Expression)
const myFunction = function (x, y) {
return x * y;
};
// アロー関数 (Arrow Function)
const myFunction = (x, y) => x * y;
// Functionコンストラクタ (Function Constructor)
const myFunction = new Function("x", "y", "return x * y");
// オブジェクトのメソッド (Object Method)
const obj = {
myFunction(x, y) {
return x * y;
},
};2. 関数宣言
これまでのチュートリアルで学んだ通り、関数は以下の構文で「宣言」されます:
function functionName(parameters) {
// 実行されるコード
}関数宣言では、function キーワードと「関数名」を使用します。
2.1 関数宣言の記述例
1行で記述する場合:
function myFunction(a, b) {return a * b}一般的な記述方法:
function myFunction(a, b) {
return a * b;
}宣言された関数は、即座に実行されるわけではありません。それらは「後で使用するために保存」され、後で呼び出された(インボークされた)時に実行されます。
また、関数宣言はコード内での宣言箇所の前でも後でも呼び出すことが可能です。
宣言の前に呼び出す例:
let x = myFunction(4, 3);
function myFunction(a, b) {
return a * b;
}宣言の後に呼び出す例:
function myFunction(a, b) {
return a * b;
}
let x = myFunction(4, 3);3. 関数式
関数式は、関数を変数の中に格納する手法です。
この時の関数は「匿名(名前がない状態)」にすることが可能です。
関数式は、コードがその行に到達した時のみ実行されます。
3.1 関数式の例
const x = function (a, b) {return a * b};関数式が変数に格納された後は、その変数を関数として使用できます。
const x = function (a, b) {return a * b};
let z = x(4, 3);4. ホイスティング (Hoisting)
関数宣言は、そのスコープの最上部へホイスティング(巻き上げ)されます。
関数式は、同様の形ではホイスティングされません。
- 関数宣言: 定義される前でも呼び出すことが可能。
- 関数式: 定義される前に呼び出すことは不可能。
4.1 ホイスティングの動作例
関数宣言は定義前に呼び出し可能:
const sum = add(2, 3); // 正常に動作する
function add(a, b) {return a + b;}関数式は定義前に呼び出すとエラーになる:
const sum = add(2, 3); // ⛔ エラーが発生する
const add = function (a, b) {return a + b;};5. 主な違い
| 特徴 | 関数宣言 (Function Declaration) | 関数式 (Function Expression) |
|---|---|---|
| 構文 | function キーワードで始まり、関数名が必須となるステートメント。 | 式や代入の一部であり、匿名(名前なし)にすることが可能。 |
| ホイスティング | コード実行前にスコープの最上部へ移動されるため、定義前でも呼び出し可能。 | 変数はホイスティングされる可能性があるが(varの場合など)、関数自体の代入は行われないため、定義後のみ呼び出し可能。 |
| 柔軟性 | グローバル、または特定のスコープ全体で利用したい汎用的な関数に適している。 | コールバック関数、即時実行関数(IIFE)、オブジェクトのプロパティへの代入など、様々なコンテキストで使用可能。 |
6. 変数に格納された関数
変数に格納された関数は、他のあらゆる値と同じように扱うことができます。
6.1 変数としての利用例
function myFunction(a, b) {
return a * b;
}
let x = myFunction(4, 3);JavaScriptの関数は、式の中で使用することも可能です。
function myFunction(a, b) {
return a * b;
}
let x = myFunction(4, 3) * 2;7. Function() コンストラクタ
関数は JavaScript の Function() コンストラクタを使用して定義することもできますが、実務で使われることは稀です。
7.1 コンストラクタの例
const myFunction = new Function("a", "b", "return a * b");
let x = myFunction(4, 3);実際には、関数コンストラクタを使用する必要はありません。上記の例は以下のように記述するのと同等です。
const myFunction = function (a, b) {return a * b};
let x = myFunction(4, 3);多くの場合、JavaScript において new キーワードの使用は避けることができます。
8. オブジェクトとしての関数
JavaScript の typeof オペレータは、関数に対して "function" を返します。
しかし、JavaScript の関数は「オブジェクト」として記述するのが最も正確です。
JavaScript の関数は、プロパティとメソッドの両方を持っています。
8.1 arguments.length プロパティ
arguments.length プロパティは、関数が受け取った「引数の数」を返します。
function multiply(a, b) {
return arguments.length;
}
// 0 を返す
multiply();
// 2 を返す
multiply(a, b);8.2 toString() メソッド
toString() メソッドは、関数を文字列として返します。
function multiply(a, b) {
return a * b;
}
let text = multiply.toString();