フリースタイルプログラミング


著者によってFederico Kereki
より読みやすく、JavaScriptコードを理解しやすく書くか?PointFreeスタイルでは、あなたと将来のメンテナの機能とその意味ではなく、マイナーな詳細に焦点を当てることによって、より良いコードを書くのに役立ちます.この記事では、プログラミングのこのスタイルに焦点を当て、その利点-だけでなく、その可能な欠点!したがって、この記事はあなたのコードを強化するために機能的プログラミング技術を適用する傾向にありますchaining and fluent interfaces .

PointFreeスタイルは何ですか?


PointFreeスタイルは、各関数アプリケーションの引数を指定する必要はありません.「点」という用語は関数パラメタを表します、そして、pointfreeはそのようなパラメタを命名しないことをしなければなりません.このパラダイムでは、読者は、そのパラメータの特定の名前を気にしていない、どのような関数があるかを読者に集中させたい.

Pointfree style is also known as tacit programming by its champions, or as Pointless Programming by its detractors!


機能を組み立てるか、パイプライン化するとき、このスタイルは最もしばしば見られます.アイデアは抽象化のより高いレベルで働くことです.そして、どんな機能がするかについて集中して、パラメタが呼ばれるようなマイナーな詳細を避けます.読みにくいコードがあれば、早く理解できます.ただし、使用したり、極端に撮影した場合、PointFreeスタイルは、代わりにコードをあいまいにすることが終わる可能性があります!
ので、ポイントフリースタイルの味を得ることができる実際の例を見てみましょう!

一例


ムッシュJourdain、モリシエの遊びの性格Le Bourgeois Gentilhomme 「ブルジョワ紳士」は、彼がそれを知っていることさえなく40年以上の間散文で話すことを学んでいたことを全く驚いていました
連鎖と流暢なインターフェイスの記事では、私のコードを見ましたMastering JavaScript Functional Programming 本書では、いくつかの(基本的に無意味な)操作を定義することから始めました.
const testOdd = x => x % 2 === 1;
const testUnderFifty = x => x < 50;
const duplicate = x => x + x;
const addThree = x => x + 3;
これらの操作を順番に配列に適用しました.最初に、私たちも数字を落としたその後、残りのものを2倍にしたその後、私たちは50以上の結果を落としました、そして、最終的に、我々は残っていたものに3を加えました.
const myArray = [22, 9, 60, 24, 11, 63];

const a0 = myArray
  .filter(testOdd)
  .map(duplicate)
  .filter(testUnderFifty)
  .map(addThree);
// [ 21, 25 ]
すべての場合、関数に引数を指定しませんでした我々は、名前のようなものの代わりに名前付き関数を使用しました.filter(x => x % 2 === 1) -- これはPointFreeスタイルです!結果のコードは、よりコンパクトで、読みやすくなっています:“奇数数字だけを維持し、すべてを複製し、50の下に数字を保つ、最後にすべての3を追加します.”
PointFreeスタイルで、あなたが見るすべては、ほとんど「余分なJS」もので機能名です.このスタイルは簡潔さを成し遂げます、しかし、あなたは良い、わかりやすい機能名を選ぶ努力をしなければなりません.( A famous saying , 「コンピュータサイエンスには二つの困難なことがあります.キャッシュの無効化と命名のことは心に浮かびます.このスタイルを適用すると、2つの種類の機能が終了します:単一のタスクと明確な名前を持つ短いものと、読みやすさのためのPointFreeスタイルを使用して、他の機能を調整する長いもの.

別の例


もう一つの例を見ましょう.あなたがタイトルを変換しなければならないと仮定してくださいtitle case 最初に、いくつかの標準的な機能的なプログラミングツールを見ましょう:パイプライン化とマッピング.
const pipeline = (...fns) => fns.reduce((result, f) => (...args) => f(result(...args)));

const map = fn => arr => arr.map(fn);
パイプライニングsome proposals この時点で考慮されているのは、パラメータに最初の関数を適用し、結果を2番目の関数に渡し、それから3番目の関数になります.我々map(...) 関数はcurried バージョン.map(...) 方法は、機能的プログラミング目的に適している.
さて、これらのツールを持って、タイトルケースの文字列の作成に取り組みましょう.
const separateStringIntoWords = (str) => str.split(" ");

const firstToUpper = (str) => str[0].toUpperCase() + str.slice(1).toLowerCase();

const joinWordsIntoString = arr => arr.join(" ");

const makeTitleCase = pipeline(separateStringIntoWords, map(firstToUpper), joinWordsIntoString);
タイトルをタイトルケースに変換するにはmakeTitleCase(...) 下記の通り.
makeTitleCase("GO TO sTaTeMeNt conSIDered HARMful");
// "Go To Statement Considered Harmful"
あなたは、「1つのライナー」としてさえ、簡潔にこれを書くかもしれません-しかし、それはより明確ですか?
const makeTitleCase2 = (str) => str.split(" ").map(word => word[0].toUpperCase() + word.slice(1).toLowerCase()).join(" ");
makeTitleCase2("GO TO sTaTeMeNt conSIDered HARMful");
// "Go To Statement Considered Harmful"
このコードを理解するためには、読者は連続的にそのsplit ()個々の単語にタイトルを区切って、そのマップ各単語を大文字で変換し、join ()最後にタイトルを形成する単語を置きます.合理的に熟練したJavaScript開発者にとって、この種の仕事があなたのアプリケーションの1つの場所だけでされるならば、このコードはすばらしいかもしれません.しかし、分割、uppercase、およびいくつかの場所に参加する必要がある場合は、より読みやすくするために、私は以前のPointFreeスタイルのバージョンが理解しやすいと言うだろう.
これにさらに進みましょう.タイトルケース関数をデバッグしたいとします.そのまま.makeTitleCase(...) あなたが3つの機能を適用するということを理解することによって、正しいとみなされることができます文字列を取り、単語に分割し、その最初の文字の大文字を作ることによって、各単語をマップする2番目の1つ、いくつかの単語の文字列を作る最終的なもの.これらの補助関数はどこか他の場所で使用されるでしょう.そして、私は余分な明快さがおそらくより長いコードを補償すると思っています.

オープンソースセッション


Webアプリケーションの生産におけるデバッグは、挑戦的で、時間がかかるかもしれません.OpenReplay フルストーリー、ログオンとhotjarにオープンソースの代替手段です.それはあなたが監視し、すべてのユーザーが再生し、どのようにすべての問題のためにあなたのアプリの行動を示す再生することができます.
それはあなたのユーザーの肩を見ながら、ブラウザの検査官を開いているようなものだ.
OpenReplayは現在利用可能なオープンソースの代替手段です.

ハッピーデバッギング、現代のフロントエンドチームStart monitoring your web app for free .

問題


我々が前に言ったすべてにもかかわらず、若干の「gotchas」があなたを得るかもしれません.JavaScriptの古典的なパズルは、次の呼び出しで別の結果を説明するよう求められます.
const numbers = [22,9,60,12,4,56]
numbers.map(Number.parseFloat); // [22, 9, 60, 12, 4, 56]
numbers.map(Number.parseInt);   // [22, NaN, NaN, 5, NaN, NaN]
なぜ、これは起こっていますか?その鍵はNumber.parseFloat(...) 単一の引数を受け取ります-解析する文字列Number.parseInt(...) 番目のオプション引数を指定します.The array.map(...) メソッドは、3つの引数を持つ関数を呼び出します番号.parsefloat ()2つの余分なものを無視しますが、数です.parseint ()2番目の1つを基数とし、すべての問題が起こります.この場合、矢印関数を使用すると正しいでしょう.
numbers.map((x) => parseInt(x));   // [22, 9, 60, 12, 4, 56]
余分な(そして、ここでは不要な引数として)関数を使用するとき、関数型プログラミングは別の解決策を提供します.私たちはhigher order function 指定した関数をunary 1に変更します.
const unary = fn => (...args) => fn(args[0]);
さて、私たちの解析問題がなくなります.
numbers.map(unary(Number.parseInt));   // [22, 9, 60, 12, 4, 56]
自分で書いた関数をPointFreeスタイルで使用するときはいつでも、この種のバグを自分で公開します.気をつけて!

概要


PointFreeスタイルはJavaScriptプログラミングの有効なパターンであり、あなたが理解できる、よく名前付きの、短い単一の目的関数を持つことに集中するのを助けます.それを旋回!