JavaScriptを学習する上で、関数の定義方法を理解することは非常に重要です。
ES2015(ES6)から導入されたアロー関数は、従来の関数式よりも簡潔に記述できる上に、独特の特性を持っているため、使い方を誤ると思わぬバグを生み出す可能性があります。
本記事では、JavaScript初心者の方でも理解しやすいよう、アロー関数の基本的な使い方から、通常の関数との違い、使う上での注意点まで、具体的なコード例を交えながら丁寧に解説していきます!
- 現役のフルスタックエンジニアとして活躍中
- 開発チームリーダーとして複数プロジェクトをリード
- 副業プログラミングスクール講師として数百名以上を指導してきた教育のプロ
- プログラミングスクールのカリキュラム執筆経験あり
アロー関数の基本的な書き方
まずは実際にアロー関数を書いてみることから始めましょう。
アロー関数の基本的な構文は以下のようになります。
(引数1, 引数2, ...) => {
// 関数の処理
return 戻り値;
}
アロー関数は「=>
」(イコールと大なり記号)を使って定義します。
=>
の左側に引数を指定し、右側に関数の処理を記述します。
これを従来の関数式と比べてみましょう。
// 従来の関数式
let add = function(a, b) {
return a + b;
};
// アロー関数
let add = (a, b) => {
return a + b;
};
アロー関数では、function
キーワードが不要になり、よりシンプルに関数を定義できるのがわかります。
次に、もう少し実用的な例を見てみましょう。
配列の各要素を2倍にする関数を、従来の関数式とアロー関数で書いてみます。
// 従来の関数式
let numbers = [1, 2, 3, 4, 5];
let doubledNumbers = numbers.map(function(num) {
return num * 2;
});
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
// アロー関数
let numbers = [1, 2, 3, 4, 5];
let doubledNumbers = numbers.map(num => {
return num * 2;
});
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
どちらも同じ結果になりますが、アロー関数の方がスッキリ書けていることがわかります。
特に、関数を引数に取るmap
のようなメソッドを使う場合、アロー関数は威力を発揮します。
アロー関数のさらなる省略記法
実は、アロー関数にはさらに記述を省略できる書き方があります。
先ほどの例を使って見ていきましょう。
引数が1つの場合は()
を省略可能
アロー関数の引数が1つだけの場合、引数を囲む()
を省略することができます。
let numbers = [1, 2, 3, 4, 5];
let doubledNumbers = numbers.map(num => {
return num * 2;
});
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
処理が1文の場合は{}
とreturnを省略可能
関数の処理が1文だけの場合、{}
とreturnを省略して、より簡潔に書くことができます。
let numbers = [1, 2, 3, 4, 5];
let doubledNumbers = numbers.map(num => num * 2);
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
ここまで省略できると、一見して何をしているのかわかりにくいかもしれませんが、慣れてくると便利なので覚えておきましょう。
アロー関数と通常の関数の違い
アロー関数は便利な反面、通常の関数とは異なる特性を持っています。
ここからは、その違いを詳しく見ていきましょう。
thisの扱いが異なる
アロー関数と通常の関数で最も大きな違いは、this
の扱い方です。
まずは通常の関数におけるthis
の挙動を見てみましょう。
const person = {
name: 'Taro',
greet: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
person.greet(); // Hello, my name is Taro
ここでは、person
オブジェクトのgreet
メソッド内のthis
は、person
オブジェクトを指しています。つまり、this.name
はperson.name
と同じ意味になります。
では、同じ例をアロー関数で書いてみましょう。
const person = {
name: 'Taro',
greet: () => {
console.log(`Hello, my name is ${this.name}`);
}
};
person.greet(); // Hello, my name is
アロー関数版では、this.name
が空になってしまいました。
これは、アロー関数のthis
がその関数が定義された場所のthis
を継承するためです。
この例では、person
オブジェクトの外側、つまりグローバルなthis
を参照しています。
アロー関数のこの特性を逆手に取って、うまく使う例を見てみましょう。
const person = {
name: 'Taro',
greet: function() {
setTimeout(() => {
console.log(`Hello, my name is ${this.name}`);
}, 1000);
}
};
person.greet(); // 1秒後に "Hello, my name is Taro" と出力
ここでは、setTimeout
内でアロー関数を使っています。
もしここで通常の関数を使うと、その関数内のthis
はsetTimeout
のthis
(ブラウザではwindowオブジェクト)を参照してしまいます。
しかしアロー関数を使うことで、person.greet
メソッド内のthis
、つまりperson
オブジェクトを参照することができます。
このように、アロー関数のthis
はその定義された場所のthis
を引き継ぐというルールを理解しておくことが大切です。
arguments変数を持たない
通常の関数では、arguments
変数を使って関数に渡された引数を取得できます。
function foo() {
console.log(arguments);
}
foo(1, 2, 3); // [1, 2, 3]
しかし、アロー関数にはこのarguments
変数が存在しません。
const foo = () => {
console.log(arguments);
};
foo(1, 2, 3); // ReferenceError: arguments is not defined
代わりに、残余引数(rest parameters)を使うことができます。
const foo = (...args) => {
console.log(args);
};
foo(1, 2, 3); // [1, 2, 3]
newできない
通常の関数はコンストラクタとして使うことができますが、アロー関数はできません。
function Person(name) {
this.name = name;
}
const taro = new Person('Taro');
console.log(taro.name); // Taro
const Animal = (name) => {
this.name = name;
};
const dog = new Animal('Pochi'); // TypeError: Animal is not a constructor
アロー関数はコンストラクタとして設計されていないので、new
と一緒に使うとエラーが投げられます。
オブジェクト指向プログラミングでクラスを定義する場合は、通常の関数を使う必要があります。
JavaScriptを効率的に身につける勉強法は?
JavaScript には興味があっても、プログラミング学習をはじめたばかりであれば、以下のような疑問を持つかもしれません。
- JavaScript を身に付けてエンジニアになるには何をすればいい?
- 何から勉強すればいいんだろう?
- 効率よく勉強するには?
JavaScriptは学ぶべき内容が非常に多いため、勉強法の選び方を間違うと時間・労力・お金が無駄になってしまいます…。
そのため、こちらの記事を参考に、ご自身に最適な学習方法を選んでみませんか?