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(); // グローバルwindowfn.apply(navigator); // navigatorオブジェクトfn.call(navigator); // navigatorオブジェクトfn.bind(navigator)(); // navigatorオブジェクトアロー関数ではthisの束縛ができません。
fn = () => console.log(this);fn(); // グローバルwindowfn.apply(navigator); // グローバルwindowfn.call(navigator); // グローバルwindowfn.bind(navigator)(); // グローバルwindow対応ブラウザの違い
functionはどのブラウザでも対応しています。
アロー関数は、IEの全バージョンやMac/iOS Safariのバージョン10より前は対応していません。MacやiOSはアップデートしてくれるユーザーが多いことを考えると、IEのサポートを切るだけでアロー関数を"そのまま"使えるようになると言えます。
即時関数の書き方の違い
functionでの即時関数は、2通りの書き方ができます。
(function(){ /* 呼び出し用かっこを外側 */ })();(function(){ /* 呼び出し用かっこを内側 */ }());アロー即時関数は、かっこを外側にしか書けません。
(() => { /* 呼び出し用かっこを外側 */ })();(() => { /* 呼び出し用かっこを内側 ... エラー */ }());アロー関数に修正した時などでエラーにハマらないように、functionでもかっこは外側に書くことをお勧めします。
共通するasync-awaitの許容
function式でもアロー関数でも、asyncとawaitが使えます。
(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"})(/* 引数を設定しない */);参考リンク