JavaScript の関数とは?
JavaScript の関数 (Function) とは?
JavaScript 以外の他のプログラミング言語でも、まとまった一連の処理をあとで使い回しできるような 仕組みがある場合が多いです。ある程度の違いはあれど、それらを「関数」「プロシージャ」「サブルーチン」「メソッド」とか、そんな呼び方で呼びます。
JavaScript の場合は関数 (Function) といいます。あとで説明しますが、JavaScript では Function オブジェクトがその実体になります。
とくに、あるオブジェクトのプロパティに関連付いているものはメソッド (Method) と呼ばれます。メソッドもコンテキストが違うだけで、関数、つまり Function オブジェクトであることに違いはありません。
まずは、最も基本的な関数の使い方についてみてみましょう。
JavaScript の関数の定義と呼び出し
基本的な関数の作り方
最も基本的な関数の作り方は、 function キーワードで関数を定義することです。
例えば、hello という関数を定義するには、次のようにします。
function hello(name) {
console.log(`Hi, I'm ${name}.`);
}
function キーワードに続いて関数名を書きます。 通常、JavaScript の関数名の名前付け慣例 (naming conventions) では小文字キャメルケース (Lower Camel Case) を使うのが一般的です。
関数のなかで、オブジェクトを作成して初期化することを目的とした関数は特にコンストラクタといいます。コンストラクタ名はパスカルケース (Upper Camel Case と同じ) が一般的です。
小文字キャメルケース (lower camel case) は、最初の文字は小文字で、単語の区切りで大文字にします。(例: getFirstName() ) パスカルケースは大文字キャメルケース (upper camel case) と同じで、最初の文字も含めて単語の区切りで大文字にします。(例: ArrayBuffer )
ちなみに、キャメルはらくだ (camel) の意味で、ラクダのコブがボコボコと出ているところからきています。
( と ) の間には、 その関数が受け取る引数のリストを , 区切りで書きます。引数は受け取らなくても構いません。その場合は単に () と書きます。
上の例の hello 関数では name という名前で、引数を一つ受け取っています。
{ と } で囲まれた部分が、関数の本体になります。
インデントや改行にはほぼルールはなく、読みやすいように関数本体やブロック部があれば、その都度、インデントして記述する慣例になっています。
`Hi, I'm ${name}.` の部分は、「テンプレート文字列」などと呼ばれるものです。バックチック ` で囲んだ文字列内で ${変数名} とすると、その変数の内容を文字列のその場所に埋め込みます。
関数を実行した結果を、戻り値として呼び出し側に返すなら return で値を返します。
例えば、足し算の結果を返す関数 add 関数を作るなら、次のように return で計算結果を返します。
function add(x, y) {
let z = x + y;
return z;
}
関数の呼び出し
このhello 関数を呼ぶ (使う) には、次のようにします。
hello('Kevin');
これを実行した結果、コンソールに次のように表示されます。
Hi, I'm Kevin.
JavaScript の関数は Function オブジェクト
関数オブジェクトの作成
JavaScript の関数の実体はFunction オブジェクトです。
関数オブジェクトは、関数式 (function expression) で作成します。関数式は function(引数リスト) { 関数本体 } という形で記述し、 戻り値として関数オブジェクトが返ります。
具体例は、次のようになります。
上で見た内容の hello() 関数は、関数式を使うと次のように書くこともできます。
let hello = function(name) {
console.log(`Hi, I'm ${name}.`);
};
hello('Kevin');
ここでは関数式を使って、変数を一つ受け取る関数オブジェクトを作成しています。そして、作成された関数オブジェクトを hello という変数にセットしています。
関数を呼び出す時は、 () に、文字列の 'Kevin' を引数として渡した、 ('Kevin') を関数オブジェクトに添えることで、それを実行したということになります。
function キーワードによる関数の定義でしたこと
もう一度、function キーワードで定義した関数をみなおしておきましょう。
function hello(name) {
console.log(`Hi, I'm ${name}.`);
}
この書き方によって、主に二つのことをしたことになります。
ひとつは hello という変数の宣言です。二つ目は、それに関数オブジェクトを割当てたことになります。
関数の作り方による違いは?
上では二通りの関数の作成方法を紹介しました。
ひとつは次の形式です。
function hello(name) {
console.log(`Hi, I'm ${name}.`);
}
もうひとつは、次の関数式を使った方法です。
let hello = function(name) {
console.log(`Hi, I'm ${name}.`);
};
実は、この二つは全く同等なのではありません。
主な違いを挙げると、前者の function による定義では、プログラムが実行される前に関数が作成されます。
そのため、同じスコープ内にあれば、関数の定義前でも呼び出しが可能です。
hello('Mike'); // Hi, I'm Mike.
function hello(name) {
console.log(`Hi, I'm ${name}.`);
}
このように概念的に関数が前に存在するように振る舞うとき、関数が「吊り上げられた」(hoist された、hoisted である) という言い方をします。
以前は function による関数の定義は、常にグローバルスコープでした。 しかし、ES6 ではブロックスコープで定義できるようにっています。
strict モードにするとブロックスコープで関数定義できます。
グローバルスコープの関数は、プログラムが実行される前に作成され、Global オブジェクトのプロパティとして関数オブジェクトがセットされます。
これによって、どこからでもアクセス可能になります。
一方、関数式による関数オブジェクトの作成では、実行時に初めて関数が作成されます。 このため、変数が作成される前にそれを呼び出すことはできません。
hello('Mike');
let hello = function(name) {
console.log(`Hi, I'm ${name}.`);
};
ここでは hello という変数に関数オブジェクトを割り当てて呼び出していました。 しかし、必ずしも一度変数にセットする必要はありません。
この場合は、無名で作った関数をただちに実行するデザインパターンになり、これを特に 即時実行関数 (IIFE) といいます。 IIFE は特に有用に使える場面があります。詳しくは「即時実行関数 (IIFE)」をみてください。
以上、ここでは JavaScript の関数オブジェクトの基本的なことについて説明しました。