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"})(/* 引数を設定しない */);
参考リンク