「関数はオブジェクトである」を覚えて、より簡潔なコードを書くのを助けることができます


導入


多くの場合よりも、我々は簡潔なコードを書くことに執着している.誰がそうだろう?簡潔なコードを取るのは簡単で、通常読みやすい短いコードです.それは迅速かつ汚いコードをエレガントなコードから分離するものです.ここのキーワードはエレガントです.読みやすくするだけで簡潔で曖昧な変数名を使用して、簡潔なコードを達成するためには、実際に簡潔でないコードです.むしろ、それは他の何よりも軽微である.
開発者として、我々は可能な限りそのようなコードを書くよう努めています.JavaScriptが長年にわたって巨大なFaceliftを受け取った理由です.JavaScriptがどのように変わったかということを考慮すると、ES 6(またはEE 2015ならばEE 2015ならば)の前にそれほど古くない時代がありましたfunction 関数を定義するには、匿名または名前を付けます.たとえば、次のコードは、Click Listener(匿名関数)をHTML要素にIDveryNiceExample . 簡単にするために、リスナーはMouseEvent コンソールへのオブジェクト.
// Using "var" for added immersion
var element = document.getElementById('veryNiceExample');

// Attaches listener
element.addEventListener('click', function(event) {
  console.log(event);
});
ES 6の導入で、JavaScriptコミュニティ全体が狂ったarrow functions . 短い構文で同じことができます.
// Using "const" for added immersion
const element = document.getElementById('veryNiceExample');

// Attaches listener
element.addEventListener('click', event => {
  console.log(event);
});
それが十分に不足していない場合、巧妙な人々はさらに制限をプッシュする矢印関数の暗黙の戻り機能を利用し始めた.その後、暗黙のリターンをコード例で適用できます.Although console.log 何も返しませんが、この場合には暗黙的に返された矢印関数を使用することができます.これはただ一つの目的関数であるため、戻り値が何も実際には使用されていません.
// Using "const" for added immersion
const element = document.getElementById('veryNiceExample');

// Attaches listener
element.addEventListener('click', event => console.log(event));

関数もオブジェクトです


JavaScriptでは、すべてがオブジェクトです.オブジェクトが作成されない限りObject.create(null) , すべてはObject それ以来last link in the prototype chain . 関数はこの規則の例外ではない.プリミティブデータ型でもオブジェクトです.この点をすべて強調するにはSymbol では、object wrappers . これによって、コンストラクタを呼び出して、オブジェクトとしてプリミティブをインスタンス化することができますnew キーワード.
免責事項:パフォーマンス上の理由で、それはオブジェクトラッパーを使用することをお勧めしません.これはデモンストレーション目的だけです.
const primitiveString = 'This is a string.';
const wrapperObjectString = new String('This is a string.');

console.log(typeof primitiveString); // 'string'
console.log(typeof wrapperObjectString); // 'object'

JavaScriptはオブジェクトのような関数を扱うので、変数の値として関数を格納することができます.
// Using "const" for added immersion
const element = document.getElementById('veryNiceExample');

// Stores function through declaration
function handler(event) {
  console.log(event);
}

// Attaches listener
element.addEventListener('click', handler);
それは価値があるhandler 違うhandler() . 変数handler 保存する値を返します.この場合、それが格納する値は関数の実際の定義です.一方、handler()handler を返し、必要な値を返す.この場合、handler (定義は明示的に)return 値.したがって、handler が実行される.handler() リターンundefined .
これにより、コード例は、同じコンセプトを使用して短縮することができます.以来console.log は本質的に引数を受け入れる関数で、その定義はマウスクリックイベントのリスナーとして直接使用できます.
// Using "const" for added immersion
const element = document.getElementById('veryNiceExample');

// Attaches listener
element.addEventListener('click', console.log);
エディットアップ
では、関数のすべてのパラメータを認識しなければなりません.以下のコードの場合のように注意しないと、いくつかのパラメータ競合が発生する可能性があります.なぜこれが予想通りに動作しないかを確認してください.
['0', '1', '2'].map(parseInt); // [0, NaN, NaN]

約束をキャッチ


前の例では、オブジェクトとしての機能を考慮しても煩わしくないかもしれません.しかし、この概念はコールバック関数が遍在する約束の文脈で有用であることを証明することができます.
JavaScriptアプリケーションのプロトタイピング段階では、迅速かつ汚いコードを書くことが理解できます.高速デバッグのために、拒否された約束はしばしばエラーを記録することによって扱われます.例として、以下のコードは、GitHub REST API v3 を返します.JSON . エラーが発生した場合はcatch 受け入れるconsole.log 引数として.このようにして、Error オブジェクト.
fetch('https://api.github.com/')
  .then(res => res.json())
  .then(console.log)
  .catch(console.log);
構文的に合法的であるコードにも関わらず、他の関数をラップする1行の矢印関数(あるいは通常の関数)を見ることは、まだ一般的です.順番に、これらの1行ラッパー関数は引数として不必要に渡されます.たとえば、次のコード行を考えます.
fetch('https://api.github.com/')
  .then(res => {
    return res.json();
  })
  .then(function(data) {
    console.log(data);
  })
  .catch(err => console.log(err));
つの例は同じ操作を行い、同じ結果をもたらしますが、前者は単に簡潔でエレガントです.対照的に、後者は完全に面倒で、読みにくいです.そのような恐ろしい書かれたコードが存在する可能性は低いが(特にプロの設定で)、誇張は、ポイントを証明するためのものです.
追加のボーナスとして、JavaScriptのインタープリタ/エンジンがメモリに不要な機能を格納する必要がないので、無視してメモリが無視されます.

結論


それはコードをより簡潔にするために痛むことはありません.このようなコードを書くには、組み込み関数であっても関数を引数として他の関数に渡すことができる値だけを常に覚えておかなければなりません.これはコールバック関数の基礎です.もちろん、優雅さと読みやすさのバランスを見つけることが重要です.それは本当に生活の中で最も物事を行うような状況に依存します.
結論として、関数についてもっと批判的に考えると、いくつかのコードを保存できます.そして、コードレビュアーの正気.