永遠に機能する-メソッドから関数へ
14788 ワード
そばFederico Kereki
メソッド
では、どうしましょうか.良い考えはメソッドを等価関数に変換することです.この記事では、このような変換を実現する方法について説明します.そして、バランスのために、機能がどのようにメソッドに変換されることができるかについて見ましょう―たとえそれが我々が好むものでないとしても!
なぜ、あなたはメソッドの代わりに機能を望みますか?これにいくつかの答えがあります-そして、私たちも、この記事自体の「理由」の例を見ています.パラメータとして関数を渡すメソッドはオブジェクトにリンクされますので、簡単にパスできません.(下記のケースを参照してください)他の制限は、我々がしたいときに来ますcurrying or partial application (今後の記事には優れた話題があります)すべてが関数に適用されます.もう一つの場合:我々は(おそらく来る)を使用する場合は、関数が必要ですpipeline operator , 密接に関係しているcomposition , は関数でのみ動作する.
現在、すべてが機能であるので、彼らが適用するオブジェクトからのデカップリング方法は機能します、そして、機能は我々が対処したいものです!私たちはこの変換を「デモトダイジング」と呼びます.「解体された」方法は多様なデータ型に適用されるかもしれません.
どのように、我々は機能を「解体します」?の機能を定義することから始めましょう
矢印関数を使用すると、もう一つの方法を提供します.bind(...) 同様の結果を最初の2つの方法で実現します.
我々は以前のような高次機能を使用するアイデアを述べた
もう一つの例を持ちましょうMastering JavaScript Functional Programming 次の方法では、適切な書式指定文字列に適切な数の区切り記号と小数点以下の数字の配列を変換することができます.
OpenReplay フルストーリーとログオンにオープンソースの代替手段です.それはあなたのすべてのユーザーがあなたのアプリケーションで行うと、すべての問題のスタックの動作方法を示すすべての再生によって完全な観測能力を与える.OpenReplay自分のデータを完全に制御するためのホストです.
ハッピーデバッギング、現代のフロントエンドチームstart monitoring your web app for free .
メソッドから関数への移行方法を見ました公正さのためだけに、他の方法を見てみましょう-私たちは本当にそれをお勧めしませんが!(オブジェクトのプロトタイプにメソッドを追加することはグローバルな変更であり、他のオブジェクトとの衝突があるかもしれません.プロトタイプに新しいプロパティを追加することによって、関数を“整形”することができます.
JavaScriptを使用してメソッドを独立した関数に変換する方法と、他の方法で関数をメソッドに変換する方法を見ました.これらの技術(ほとんどは前者が正直である)はFPでよく使われる.彼らは自分自身で便利なツールを提供しますが、関数のアプリケーションやバインディングなど、あまり頻繁に使われていないメソッドでの作業においても経験を積みましょう.FPと学習を組み合わせてエキサイティングな運動!
メソッド
.map(...)
or .filter(...)
配列で利用可能ですが、例えば文字列に適用する場合はどうですか?文字をテストして、すべての文字が、すなわち、母音であることを保証するために文字列をテストすることができましたが.every(...)
配列を使ってください.(はい、正規表現を使って文字列をテストすることはできますが、これは必ずしも解決ではないし、正規表現を使うことも問題や困難をもたらします).さらに別の問題:私たちは、Aprevious article シリーズではnot(...)
メソッドを無効にする代わりに関数で動作します.では、どうしましょうか.良い考えはメソッドを等価関数に変換することです.この記事では、このような変換を実現する方法について説明します.そして、バランスのために、機能がどのようにメソッドに変換されることができるかについて見ましょう―たとえそれが我々が好むものでないとしても!
メソッドから関数へ
なぜ、あなたはメソッドの代わりに機能を望みますか?これにいくつかの答えがあります-そして、私たちも、この記事自体の「理由」の例を見ています.パラメータとして関数を渡すメソッドはオブジェクトにリンクされますので、簡単にパスできません.(下記のケースを参照してください)他の制限は、我々がしたいときに来ますcurrying or partial application (今後の記事には優れた話題があります)すべてが関数に適用されます.もう一つの場合:我々は(おそらく来る)を使用する場合は、関数が必要ですpipeline operator , 密接に関係しているcomposition , は関数でのみ動作する.
現在、すべてが機能であるので、彼らが適用するオブジェクトからのデカップリング方法は機能します、そして、機能は我々が対処したいものです!私たちはこの変換を「デモトダイジング」と呼びます.「解体された」方法は多様なデータ型に適用されるかもしれません.
どのように、我々は機能を「解体します」?の機能を定義することから始めましょう
myObject.someMethod(parameters)
to someMethod(myObject, parameters)
. 変換では、新しい関数への最初のパラメータが適用されるオブジェクトになります.(これは他の言語で何が起こるかに似ています.例えばPythonでは、任意のメソッドへの最初のパラメータはself
を返します.我々は今、いくつかの代替と同等の方法で変換を行うことができます.The .apply(...) , .call(...) メソッドは役立ちます.const demethodize1 =
(fn) =>
(arg0, ...args) =>
fn.apply(arg0, args);
const demethodize2 =
(fn) =>
(arg0, ...args) =>
fn.call(arg0, ...args);
The .apply(...)
メソッドは最初の引数を使用して関数fnを呼び出します.arg0
) ASthis
, を返します.The .call(...)
解決策は似ていますが、引数を個別に提供します.矢印関数を使用すると、もう一つの方法を提供します.bind(...) 同様の結果を最初の2つの方法で実現します.
const demethodize3 =
(fn) =>
(arg0, ...args) =>
fn.bind(arg0, ...args)();
バインドはすべてのパラメータセットを持つ関数を生成し、それを呼び出します.あなたは尋ねるかもしれません:なぜ私はシングルアウトarg0
? 以下のコードはうまくいきませんか?単純な答え:私はちょうど同じスタイルのコードを示したかったです.const demethodize3b =
(fn) =>
(...args) =>
fn.bind(...args)();
そして、好奇心旺盛な場合は、まだ機能を解体するもう一つの方法があります-しかし、おそらく理解するのは難しい!以下のコードはテイラースミスによって書かれ、彼のブログでリーランドリチャードソンによって説明されたcheck it out! 説明はよく読む価値があり、我々はここでそれを複製しません.const demethodize4 = Function.prototype.bind.bind(
Function.prototype.call
);
ところで、私たちは、すべての解決策は、実際には“1つのライナー”-私は明確な書式設定を選んだが、観察することができます.私たちが同じ結果を達成するいくつかの方法を見た今、彼らが本当に働くと確認しましょう!いくつかの例
我々は以前のような高次機能を使用するアイデアを述べた
every(...)
文字列がすべての母音であるかどうかを調べます.以下のようにします.const isVowel = (x) =>
['a', 'e', 'i', 'o', 'u'].includes(x);
const every = demethodize(Array.prototype.every);
console.log(every('abcd', isVowel)); // false
console.log(every('eieio', isVowel)); // true
述語関数isVowel(...)
パラメータが母音であるかどうかをチェックします.私たちはevery(...)
関数は、我々が見たデモジゼーション機能のいずれかを適用して選んでください最後に、我々は、文字列がすべての母音であるかどうかチェックすることができます.いいねもう一つの例を持ちましょうMastering JavaScript Functional Programming 次の方法では、適切な書式指定文字列に適切な数の区切り記号と小数点以下の数字の配列を変換することができます.
const toLocaleString = demethodize(
Number.prototype.toLocaleString
);
const numbers = [2209.6, 124.56, 1048576];
const strings = numbers.map(toLocaleString);
console.log(strings); // "2,209.6", "124.56", "1,048,576"
我々は解体している.toLocaleString(...)
関数を.map(...)
コール微妙!我々は、より良いものに行くことさえできて、解体することさえできました.map(...)
自身.const map = demethodize(Array.prototype.map);
const strings2 = map(numbers, toLocaleString);
// same result as above
最後の行は、本質的に機能的ですいいえメソッドの任意の場所、純粋FPスタイル全体!これは記事の冒頭で述べた事例の一つです.toLocaleString(...)
関数には、他の関数に渡すことができます.オープンソースセッション
OpenReplay フルストーリーとログオンにオープンソースの代替手段です.それはあなたのすべてのユーザーがあなたのアプリケーションで行うと、すべての問題のスタックの動作方法を示すすべての再生によって完全な観測能力を与える.OpenReplay自分のデータを完全に制御するためのホストです.
ハッピーデバッギング、現代のフロントエンドチームstart monitoring your web app for free .
関数からメソッド
メソッドから関数への移行方法を見ました公正さのためだけに、他の方法を見てみましょう-私たちは本当にそれをお勧めしませんが!(オブジェクトのプロトタイプにメソッドを追加することはグローバルな変更であり、他のオブジェクトとの衝突があるかもしれません.プロトタイプに新しいプロパティを追加することによって、関数を“整形”することができます.
const methodize = (obj, fn) => {
obj.prototype[fn.name] = function (...args) {
return fn(this, ...args);
};
};
を使用する必要がありますfunction(...)
宣言(矢の関数ではない)this
著作物続きを読むon that topic . それを使用するには、文字列を取り、新しい文字列を生成する関数を持つことができます.以下に例を示します.const separate = (str, x) => str.split('').join(x);
console.log(separate('eieio', '-')); // e-i-e-i-o
我々はすぐに新しい.separate(...)
すべての文字列へのメソッド.methodize(String, separate);
console.log('slowly'.separate(' ... '));
// s ... l ... o ... w ... l ... y
我々はそれを得た!つだけ問題がありますどのように関数を定義するかによって、名前があるかもしれません.後者の場合はmethodize(...)
関数は単にクラッシュします!結論として
JavaScriptを使用してメソッドを独立した関数に変換する方法と、他の方法で関数をメソッドに変換する方法を見ました.これらの技術(ほとんどは前者が正直である)はFPでよく使われる.彼らは自分自身で便利なツールを提供しますが、関数のアプリケーションやバインディングなど、あまり頻繁に使われていないメソッドでの作業においても経験を積みましょう.FPと学習を組み合わせてエキサイティングな運動!
Reference
この問題について(永遠に機能する-メソッドから関数へ), 我々は、より多くの情報をここで見つけました https://dev.to/asayerio_techblog/forever-functional-from-methods-to-functions-and-back-4h0kテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol