thisキーワードの扱いの違い

コールバックで呼び出された場合のthisは、functionの場合呼び出し元のオブジェクトを指します。

elem.addEventListener('click', function () {
console.log(this); // 呼び出し元のelem
});
elem.addEventListener('click', () => {
console.log(this); // グローバルのwindow
});

アロー関数の場合は、呼び出し元のオブジェクトが属するスコープでのthisと同じになります。

console.log(this, 'スコープA');
const obj = {
price: 240,
getWithFnExpr: function () {
console.log(this); // objの中身
},
getWithArrowFn: () => {
console.log(this, 'スコープA'); // この場合はグローバルのwindow
}
};
obj.getWithFnExpr();
obj.getWithArrowFn();

apply, call, bindでの違い

functionではいずれも機能します。

fn = function () { console.log(this) };
fn(); // グローバルwindow
fn.apply(navigator); // navigatorオブジェクト
fn.call(navigator); // navigatorオブジェクト
fn.bind(navigator)(); // navigatorオブジェクト

アロー関数ではthisの束縛ができません。

fn = () => console.log(this);
fn(); // グローバルwindow
fn.apply(navigator); // グローバルwindow
fn.call(navigator); // グローバルwindow
fn.bind(navigator)(); // グローバルwindow

対応ブラウザの違い

functionはどのブラウザでも対応しています。

アロー関数は、IEの全バージョンやMac/iOS Safariのバージョン10より前は対応していません。MacやiOSはアップデートしてくれるユーザーが多いことを考えると、IEのサポートを切るだけでアロー関数を"そのまま"使えるようになると言えます。

即時関数の書き方の違い

functionでの即時関数は、2通りの書き方ができます。

(function(){ /* 呼び出し用かっこを外側 */ })();
(function(){ /* 呼び出し用かっこを内側 */ }());

アロー即時関数は、かっこを外側にしか書けません。

(() => { /* 呼び出し用かっこを外側 */ })();
(() => { /* 呼び出し用かっこを内側 ... エラー */ }());

アロー関数に修正した時などでエラーにハマらないように、functionでもかっこは外側に書くことをお勧めします。

共通するasync-awaitの許容

function式でもアロー関数でも、asyncawaitが使えます。

(async function (duration) {
await new Promise(function (resolve) {window.setTimeout(resolve, duration)});
console.log('function文を使った遅延'); // 約500ミリ秒後に出力
})(500);
(async duration => {
await new Promise(resolve => {setTimeout(resolve, duration)});
console.log('アロー関数を使った遅延'); // 約500ミリ秒後に出力
})(500);

共通するデフォルト引数の許容

function式でもアロー関数でも、引数のデフォルト値を設定できます。アロー関数の場合、引数が一つだけの場合はかっこを省略できますが、デフォルト引数を使う場合は省略できません。

(function (param = 6) {
console.log(param); // 6
})(/* 引数を設定しない */);
((param = 6) => {
console.log(param); // 6
})(/* 引数を設定しない */);

共通する引数での分割代入

function式でもアロー関数でも、引数での分割代入ができます。

(function ({person = {name: '佐藤'}, pref = '東京'} = {}) {
console.log(person); // {name: '佐藤'}
console.log(pref); // "東京"
})(/* 引数を設定しない */);
(function ([foo = 'bar'] = []) {
console.log(foo); // "bar"
})(/* 引数を設定しない */);
(({person = {name: '佐藤'}, pref = '東京'} = {}) => {
console.log(person); // {name: '佐藤'}
console.log(pref); // "東京"
})(/* 引数を設定しない */);
(([foo = 'bar'] = []) => {
console.log(foo); // "bar"
})(/* 引数を設定しない */);

参考リンク