最近、関数型プログラミングの入門書を読んでいて、自分なりにまとめてみましたので、興味がある方、必要な方はご覧ください。
1. 関数型プログラミングとは
関数型プログラミングは主に数学の関数とその考え方に基づいています。まず数学の関数、つまり
y = f(x)
、つまり関数 f について復習しましょう。 (x ) は x をパラメーターとして、y を結果として受け取ります。これにはいくつかの重要な点が含まれます:
1. 関数は常に値を返す必要があります
3.関数は、外部環境ではなく、受信したパラメーター (x など) に基づいて実行される必要があります。 4. 指定された x に対して、一意の y のみが出力されます。この関数を分析するために、まず次の例を見てみましょう。 3 番目の項目は、関数は外部環境ではなく、受け取ったパラメーターに従って実行する必要があります。ここでの関数 CalculateTax は外部のpercentValueに依存しているため、この関数を数学的な意味での関数と呼ぶことはできません。では、どうすればこの関数を数学的な意味での関数に変換できるでしょうか。非常に単純です
var CalculateTax = (value,percentValue) => {return value/100 * (100 +percentValue)};
それでは、関数型プログラミングを簡単な技術用語で定義してみましょう。関数型プログラミングは、関数が入力と出力のみに依存して独自のロジックを完成させるパラダイムです。これにより、関数が複数回呼び出された場合に同じ結果が返されるようになります。この関数は外部環境変数を変更しません。
2. 参照の透明性例として// 一个计税函数
var percentValue = 5;
var calculateTax = (value) => {return value/100 * (100 + percentValue)};
関数内のグローバル変数に依存せず、単に入力を返す単純な関数を定義します。ここで、それが
var identity = (i) => { return i };
のような他の関数呼び出しの間に適用されると仮定します。 参照透過性の定義に従って、それを
sum(4,5) + identity(1);に変換できます。 このプロセスは置換モデルと呼ばれ、関数の結果を直接置き換えることができます (主に、この関数のロジックは他のグローバル変数に依存しません)。
関数は指定された入力結果に対して同じ値を返すため、実際にそれをキャッシュすることができます。たとえば、階乗を計算する関数「factorial」があります。階乗を計算するために引数を受け取ります。たとえば、5 の階乗は 120 です。ユーザーが 2 回目に 5 の階乗を入力すると、参照の透明性により (同じ入力に対して同じ結果が返されます)、結果が 120 であることがわかりますが、マシンにはそれを認識させる必要があります。マシンが結果をキャッシュすることで、今後の呼び出しで結果を再度計算することなく直接返すことができます。これは、関数型プログラミングにおける参照の透過性とキャッシュ可能なコードの重要性を示しています。
3. 関数型、宣言型、抽象型 宣言型プログラミングとは何ですか? 配列内のすべての要素を出力したいとすると、次のメソッド sum(4,5) + 1;
を使用できます。このコードでは、コードに何を実行するかを正確に指示します。例: 配列の長さの取得、配列のループ、インデックスによる各要素の取得。これは命令型プログラミングです。命令型プログラミングは、コンパイラーに何をすべきかを指示することを支持します。
var array = [1,2,3]; for(let i = 0; i < array.length; i++){ console.log(array[i]) }
上記のコードでは、配列の長さの取得、配列のループ、インデックスを使用した配列要素の取得などを削除しました。私たちが気にするのは、何をするか (配列要素の出力など)、配列の長さの取得、ループなどはすべてマシンによって行われます。私たちが気にする必要があるのは、何を行うかだけであり、方法ではありません。宣言型プログラミング
関数型プログラミングの提案 コード内の他の場所で再利用できる抽象的な方法で関数を作成します。
4. 純粋関数
純粋関数とは何ですか?純粋関数関数は、指定された入力に対して同じ出力を返します。たとえば、
var arr = [1,2,3]; arr.forEach((ele) => { console.log(ele) })
上の double は、同じ入力に対して常に同じ出力を返すため、純粋関数です。純粋な関数は参照透過性に従うため、単純に double(5) を 10 に置き換えることができます。では、純粋関数の何がすごいのでしょうか?見てみましょう1.4.1 純粋関数はテスト可能なコードを生成します
不純関数には副作用があります。例として前の税金計算関数を見てみましょうvar double = (value) => value * 2;この関数は主に外部環境に依存するため、純粋関数ではありません。そのロジックを計算し、外部環境が変化すると結果に影響を与えます。したがって、純粋関数の主な特徴は、外部変数に依存せず、外部変数を変更すべきではないことです。外部変数を変更すると、他の関数の動作が変更される可能性があります。つまり、副作用が発生し、システムの動作が予測不能になる可能性があります。 1.4.2 合理的なコード
double function など、名前から関数の機能を推測する必要があります
var double = (value) => value * 2;
我们可以通过函数名轻易的推出这个函数会把给定的数值加倍,因此根据引用透明性,我们可以直接把 double(5) 替换成 10。还有一个例子,Math.max(3,4,5,6) 结果是什么?虽然我们只看到了函数的名字,但是我们很容易看出结果,我们看到实现了吗?并没有,为什么,就是因为 Math.max 是纯函数啊!!!
5、 并发代码
纯函数允许我们并发的执行代码,因为纯函数不会改变它的环境,这意味着我们根本不需要担心同步问题。当然,js 是单线程的,但是如果项目中使用了 webworker 来并发执行任务,该怎么办?或者有一段 Node 环境中的服务端代码需要并发的执行函数,又该怎么办呢?
// 非纯函数代码 let global = 'something' let function1 = (input) => { // 处理 input // 改变 global global = "somethingElse" } let function2 = () => { if(global === "something"){ // 业务逻辑 } }
如果我们需要并发的执行 function1 和 function2,假设 function1 在 function2 之前执行,就会改变 function2 的执行结果,所以并发执行这些代码就会造成不良的影响,现在把这些函数改为纯函数。
let function1 = (input,global) => { // 处理 input // 改变 global global = "somethingElse" } let function2 = (global) => { if(global === "something"){ // 业务逻辑 } }
此处我们把 global 作为两个函数的参数,让它们变成纯函数,这样并发执行的时候就不会有问题了。
6、可缓存
既然纯函数对于给定的输入总能返回相同的输出,那么我们就能缓存函数的输出,例如
var doubleCache = (value) => { const cache = {}; return function(value){ if(!cache[value]){ cache[value] = value * 2 console.log('first time') } return cache[value]; } } var double = doubleCache(); double(2) // first time,4 double(2) // 4 // 或者直接使用立即执行函数 var double = ((value) => { const cache = {}; return function(value){ if(!cache[value]){ cache[value] = value * 2 console.log('first time') } return cache[value]; } })() double(2) // first time,4 double(2) // 4
这个函数中,假设我们第一次输入 5,cache 中并没有,于是执行代码,由于闭包的存在,cache[5] = 10,第二次我们调用的时候,cache[5] 存在,所以直接 return 10,看到了吗?这就是纯函数的魅力!!!别忘记这是因为纯函数的引用透明性。
7、 管道与组合
纯函数应该被设计为一次只做一件事,并且根据函数名就知道它所做的事情。
比如 linux 系统下有很多日常任务的命令,如 cat 用于打印文件内容,grep 用于搜索文件,wc 用于计算行数,这些命令一次只解决一个问题,但是我们可以用管道或组合来完成复杂的任务。假设我们需要在一个文件中找到一个特定的名称并统计它的出现次数,在命令行要输入如下指令
cat jsBook | grep -i “composing” | wc
上面的命令通过组合多个函数解决了我们的问题。组合不是 linux 命令独有的,它们是函数式编程范式的核心。
我们把它们称为函数式组合。来看一个 compose 函数的例子
var add1 = (value) =>{ return value+1 }; var double = (value) => {return value*2 }; var compose = (a,b) => { return (c) => { return a(b(c)); } } var doubleAndAdd1 = compose(add1,double); doubleAndAdd1(5) // 打印 5 * 2 + 1 = 11
compose 函数返回一个函数,将 b 的结果作为 a 的参数,这里就是将 double 的结果作为 add1 的参数,来实现了函数的组合。
8、 纯函数是数学函数
还记得我们之前的缓存函数吗,假设我们多次调用 double 对象,那么 cache 中就会变成这样
{ 1: 2, 2: 4, 3: 6, 4: 8, 5: 10 }
假设我们设置 double 的输入范围限制为 1 - 5,而且我们已经为这个范围建立的 cache 对象,因此只要参照 cache 就能根据指定输入返回指定输出。也就是一一对应的关系。
那么数学函数的定义是什么呢?
在数学中,函数是一种输入集合和可允许的输出集合之间的关系,具有如下属性:每个输入都精确地关联一个输出。函数的输入称为参数,输出称为值。对于一个给定的函数,所有被允许的输入集合称为该函数的定义域,而被允许的输出集合称为值域。
上面的定义和纯函数完全一致,例如在 double 中,你能找到定义域和值域吗?当然可以!通过这个例子,可以很容易看到数学函数的思想被借鉴到函数式范式的世界
9、 我们要做什么?
我们将通过学习,构建出一个 ES6-Functional 的函数式库,通过构建的过程,我们将理解如何使用 JavaScript 函数,以及如何在日常工作中应用函数式编程。
10、小结
这一节我们只是简单的介绍了函数式编程的概念,以及什么是纯函数,其中最重要的就是引用透明性。然后研究了几个短小的例子,通过例子来加深对函数式编程的理解。接下来我们将一步一步深入了解函数式编程。
以上が関数型プログラミングの概要と概要 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

メモ帳++7.3.1
使いやすく無料のコードエディター

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。
