関数定義
JavaScriptの関数は様々な方式で定義することができます。
それぞれの方式が適しているシーンを理解し、適切に使い分けることが重要です。
以下にそのいくつかを示します。
関数宣言
最も基本的な関数の定義方法で、名前を持つ関数を作成します。
関数宣言はコードが実行される前に読み込まれるため、コードのどこからでも呼び出すことが可能です。
この性質は、ある程度大きな処理をモジュール化し、何度も使用するようなシチュエーションで有用です。
function greet() {
console.log('Hello, world!');
}
greet(); // 実行 => Hello, world!
関数式
関数を変数に代入する方法です。
これは匿名関数または名前付き関数を変数に割り当てることができます。
関数式は変数のスコープに依存するため、ローカルスコープで関数を制限したい場合に便利です。
また、即時実行関数など、特定のパターンで使われることがあります
let greet = function() {
console.log('Hello, world!');
}
greet(); // 実行 => Hello, world!
アロー関数
ES6で導入された新しい関数の定義方法で、短く書くことができる他、thisの挙動が変わります。
一般的にはコールバック関数や配列操作(map, filter, reduceなど)の中でよく使われます。
const greet = () => {
console.log('Hello, world!');
}
greet(); // 実行 => Hello, world!
即時実行関数
関数を定義と同時に実行します。
一度だけ実行したいコードを隔離するために使われます。
関数内で定義された変数はその関数のスコープ内に閉じ込められるため、グローバルスコープを汚染せずにコードを実行できます。
(function() {
console.log('Hello, world!');
})();
// 即時実行 => Hello, world!
(() => {
// 関数の内容
})();
(function() {
let privateVariable = "I'm private!";
console.log(privateVariable); // "I'm private!"
})();
console.log(typeof privateVariable); // "undefined"
この例では変数(privateVariable)は即時実行関数内でしかアクセスできません。
このような特性を利用して、他のコードとの名前の衝突を防いだり一時的な作業変数を隔離したりすることができます。
※最近のJavaScript(ES2020以降)では、
クラス内で"#"を使ってprivateメソッド関数を定義することができます。
class MyClass {
#privateMethod() {
return "Hello, World!";
}
callPrivateMethod() {
return this.#privateMethod();
}
}
const myInstance = new MyClass();
console.log(myInstance.callPrivateMethod()); // "Hello, World!"
console.log(myInstance.#privateMethod()); // Error: Private field '#privateMethod' must be declared in an enclosing class
コンストラクタ関数(非推奨)
JavaScriptのコンストラクタを用いて関数を定義する方法もありますが、通常は使用されません。
なぜなら、関数の内容が文字列として評価されるため、パフォーマンス上の問題やセキュリティリスク、そしてスコープの問題が伴うためです。
let greet = new Function('console.log("Hello, world!");');
greet(); // 実行 => Hello, world!
以上のようにJavaScriptでは、様々な方法で関数を定義する事ができます。
これらの関数の性質を知っておくと、より効率的にコードを書き、他の人が書いたコードを理解しやすくなります。