アロー関数と通常の関数の違い
JavaScriptにおける「Arrow Functions」と「Functions」の比較
日本語訳
JavaScriptにおいて、「Arrow Functions」(アロー関数)と「Functions」(通常の関数)は、その構文や挙動においていくつかの違いがあります。
Arrow Functions
super
キーワードを使用できない。arguments
オブジェクトへのアクセスが制限される。this
キーワードの束縛が異なる。- 簡潔な構文で記述できる。
Functions
this
キーワードの束縛は呼び出しコンテキストによって決まる。- 伝統的な関数の構文を使用する。
等価性と互換性
多くの場合、Arrow Functionsと通常のFunctionsは互換的に使用できます。しかし、以下のようなケースでは注意が必要です。
- superキーワードの使用
Arrow Functionsはsuper
キーワードを使用できないため、クラスメソッドでsuper
を使用する必要がある場合は、通常の関数を使用する必要があります。 - argumentsオブジェクトの使用
Arrow Functionsはarguments
オブジェクトにアクセスできないため、関数内で引数の情報を取得する必要がある場合は、通常の関数を使用する必要があります。 - thisキーワードの挙動
Arrow Functionsは、外側のスコープのthis
を継承するため、this
の値が重要である場合、通常の関数を使用する必要があります。
アロー関数と通常の関数の違い:具体的なコード例で解説
thisの束縛の違い
// 通常の関数
const obj = {
name: 'Taro',
sayHello: function() {
console.log('Hello, my name is ' + this.name);
}
};
obj.sayHello(); // 出力: Hello, my name is Taro
// アロー関数
const obj2 = {
name: 'Jiro',
sayHello: () => {
console.log('Hello, my name is ' + this.name);
}
};
obj2.sayHello(); // 出力: Hello, my name is undefined (またはグローバルオブジェクトのnameプロパティ)
- 解説
- 通常の関数では、
this
は関数を呼び出したオブジェクトを指します。
- 通常の関数では、
argumentsオブジェクトへのアクセス
// 通常の関数
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(sum(1, 2, 3)); // 出力: 6
// アロー関数
const sumArrow = () => {
// argumentsは使用できない
};
- 解説
- 通常の関数では、
arguments
オブジェクトを使って、関数に渡された全ての引数にアクセスできます。 - アロー関数では、
arguments
オブジェクトは使用できません。代わりに、残余引数(...args
)を使って、全ての引数を配列として受け取ることができます。
- 通常の関数では、
newキーワードの使用
// 通常の関数
function Person(name) {
this.name = name;
}
const person = new Person('Hanako'); // これは可能
// アロー関数
const PersonArrow = (name) => {
this.name = name;
};
const personArrow = new PersonArrow('Hanako'); // これはエラー
- 解説
- 通常の関数は
new
キーワードを使って、新しいオブジェクトを作成することができます(コンストラクタとして使用)。 - アロー関数は
new
キーワードと一緒に使用することはできません。
- 通常の関数は
superキーワードの使用
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
bark = () => {
console .log(`${this.name} says Woof!`); // thisはDogではなく、グローバルオブジェクトを指す
}
}
- 解説
- superキーワード
アロー関数では、super
キーワードは使用できません。 - newキーワード
アロー関数では、new
キーワードと一緒に使用できません。 - argumentsオブジェクト
アロー関数では、arguments
オブジェクトは使用できません。 - thisの束縛
アロー関数は、this
が外側のスコープを指すという特徴があります。
どちらを選ぶべきか
- 柔軟性
通常の関数は、this
の束縛を自由に制御したり、arguments
オブジェクトを利用したりするなど、より柔軟な記述が可能です。 - 簡潔な記述
アロー関数は、this
の束縛が不要な場合や、短い関数を記述したい場合に便利です。
どちらを使うべきかは、コードの文脈や、this
やarguments
などの機能をどのように利用したいかによって決まります。
- ECMAScript 2022からは、
class
フィールドの初期化子でアロー関数を使用できるようになりました。 - アロー関数と通常の関数、どちらが良いかという一概な答えはありません。それぞれの特性を理解し、適切な場面で使い分けることが重要です。
アロー関数と通常の関数の代替方法と使い分け
アロー関数と通常の関数には、それぞれ特徴と得意な分野があります。どちらを使うべきか迷った場合は、以下の点を考慮して、適切な方法を選択しましょう。
thisの束縛が重要な場合
- 例
イベントハンドラー、オブジェクト指向プログラミングなど - 通常の関数
this
の値を明示的に制御したい場合、通常の関数を使用します。bind
メソッドなどを活用することで、this
の値を固定できます。
- 例
可変長引数の関数 - 通常の関数
全ての引数にアクセスしたい場合、arguments
オブジェクトを使用できる通常の関数を使用します。
コンストラクタとして使用する場合
- 例
クラスの作成 - 通常の関数
new
キーワードを使ってインスタンスを作成したい場合は、通常の関数(コンストラクタ)を使用します。
簡潔な記述をしたい場合
- 例
配列の要素を別の配列に変換する処理など - アロー関数
短い関数や、this
の束縛が問題にならない場合は、アロー関数を使用することでコードを簡潔に記述できます。
thisの束縛を固定したい場合
- 例
イベントハンドラーで、this
が別のオブジェクトを指すようにしたい場合 - bindメソッド
通常の関数のbind
メソッドを使うことで、this
の値を固定できます。
残余引数(Rest parameter)
- アロー関数、通常の関数
...args
のように記述することで、残りの引数を配列として受け取ることができます。
- 通常の関数
this
の制御、arguments
オブジェクトの利用、コンストラクタとして使用する場合に適しています。 - アロー関数
簡潔な記述、this
の束縛がシンプルな場合に適しています。
- 関数の役割
- 引数の扱い方
this
の束縛- コードの可読性
などを考慮して、適切な方法を選択しましょう。
コード例
// thisの束縛
const obj = {
name: 'Taro',
// 通常の関数
sayHello: function() {
console.log(this.name);
},
// アロー関数 (thisはobjを指さない)
sayHelloArrow: () => {
console.log(this.name);
}
};
// argumentsオブジェクト
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
// 残余引数
const sumArrow = (...args) => {
return args.reduce((acc, cur) => acc + cur, 0);
};
// コンストラクタ
function Person(name) {
this.name = name;
}
- アロー関数は、
new
キーワードでインスタンスを作成することはできません。 - アロー関数は、
this
の束縛が異なるため、クラスメソッド内でsuper
を使うことはできません。
javascript ecmascript-6 arrow-functions