ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptをより機能的にする5つの方法

JavaScriptをより機能的にする5つの方法

Joseph Gordon-Levitt
Joseph Gordon-Levittオリジナル
2025-02-09 09:40:13941ブラウズ

5 Ways to Make Your JavaScript More Functional

この記事では、機能プログラミングの概念を簡単に紹介し、JavaScriptコードの機能スタイルを改善する5つの方法を説明します。

コアポイント

  • 関数プログラミングは、コマンドリストではなく機能とそのアプリケーションを使用するプログラミングパラダイムです。それはより抽象的であり、数学に由来します。 JavaScriptは、機能が最初のタイプのオブジェクトであるため、機能的なプログラミングに特に適しています。
  • 純粋な関数は、機能プログラミングの重要な部分です。同じ引数を考えると、それらは常に同じ値を返し、関数の範囲外のものを変更しません。彼らはあなたのコードをポートしてテストしやすくします。
  • 機能プログラミングでは、変数は変更されていません。変数を設定した後、プログラム全体でその状態のままである必要があります。これは、constを使用して常に変数を宣言することで実現できます。
  • JavaScriptの機能プログラミングで矢印関数と3成分演算子を使用することをお勧めします。矢印関数には暗黙の戻り値があり、出力から出力マッピングの視覚化に役立ちます。三元演算子は常に値を返す式であるため、戻り値が存在することを確認することが有用です。
  • 機能的プログラミングでの使用を使用することは、それらが可変状態に依存するため、避ける必要があります。代わりに、再帰的および高次配列メソッドを使用する必要があります。さらに、タイプの一貫性を維持するために、タイプの強制を避ける必要があります。これは、関数を宣言する前にタイプの宣言コメントを書くことで実行できます。 for

機能プログラミングとは何ですか?

関数プログラミングは、

命令プログラミング言語で使用されるコマンドのリストではなく、機能とそのアプリケーションを使用するプログラミングパラダイムです。

これは、数学のルーツを備えたより抽象的なスタイルのプログラミングです。特に、1936年に数学者アロンゾ教会によって計算モデルの正式なモデルとして設計された数学的枝。これは、ある式を別の式にマッピングする表現と関数で構成されています。基本的に、これは機能プログラミングで行うことです。関数を使用して、値を異なる値に変換します。

この記事の著者は、近年、機能的なプログラミングに恋をしています。より機能的なスタイルを促進するJavaScriptライブラリを使用し始め、Haskellでコードを書く方法を学ぶことで深海にまっすぐ飛び込んだ。

Haskellは、ScalaとClojureと同様に、1990年代に開発された純粋に機能的なプログラミング言語です。これらの言語を使用すると、機能的なスタイルでエンコードすることを余儀なくされます。 Haskellを学習すると、機能プログラミングのすべての利点についての真の理解が得られます。

JavaScriptは、マルチパラダイム言語です。これは、命令的、オブジェクト指向、または機能的なスタイルでプログラムするために使用できるためです。ただし、関数はファーストクラスのオブジェクトであるため、機能スタイルに特に適合します。つまり、変数に割り当てることができます。これはまた、関数を他の関数(通常はコールバックと呼ばれる)の引数として、または他の関数の返品値として渡すことができることを意味します。他の関数を返すか、パラメーターとして他の関数を受け入れる関数は、高次関数と呼ばれ、機能プログラミングの基本的な部分です。

近年、特に反応の台頭後、機能的なスタイルでJavaScriptをプログラミングすることがますます人気が高まっています。 Reactは、機能的方法に適した宣言APIを使用するため、機能的なプログラミング原理をしっかりと把握することで、Reactコードが改善されます。

なぜ機能プログラミングがそれほど優れているのですか?

要するに、機能的なプログラミング言語は、多くの場合、コードが簡潔で明確でエレガントであることがよくあります。通常、コードはテストが簡単で、問題なくマルチスレッド環境で実行できます。

多くの異なるプログラマーと話をすると、皆から機能的なプログラミングについてまったく異なる意見を得ることができます。私たち(この記事の著者)は「Love It」の側にいますが、特に私たちが通常教える方法とは大きく異なるため、誰もが料理ではないことを完全に理解しています。

しかし、機能プログラミングをマスターし、思考プロセスがクリックした後、第二の性質になり、コードの書き方を変えます。

ルール1:関数を浄化

機能プログラミングの重要な部分は、書く機能が「純粋」であることを確認することです。この用語に慣れていない場合、純粋な機能は基本的に次の条件を満たしています。

引用の透明性があります。これは、同じ引数を考えると、関数が常に同じ値を返すことを意味します。任意の関数呼び出しは、返品値に置き換えることができ、プログラムは引き続き同じ方法で実行されます。
  • 副作用はありません。これは、関数が関数の範囲外に変更を加えないことを意味します。これには、グローバル価値の変更、コンソールへの記録、またはDOMの更新が含まれます。
  • 純粋な関数
  • は、少なくとも1つのパラメーターを持っている必要があり、
  • は値を返す必要があります。慎重に考えると、パラメーターを受け入れない場合、使用するデータはありません。値を返さない場合、関数のポイントは何ですか?

純粋な関数は最初は完全に必要ではないように見えるかもしれませんが、不純な関数を使用するとプログラム全体の変化が生じ、いくつかの深刻な論理エラーが発生します。 例: 不純な関数では、

関数は可変変数

に依存します。たとえば、プログラムの後半で

変数が更新された場合、

関数は同じ入力を使用してブール値を返す可能性があります。

<code class="language-javascript">// 不纯
let minimum = 21;
const checkAge = (age) => age >= minimum;

// 纯
const checkAge = (age) => {
    const minimum = 21;
    return age >= minimum;
};</code>
次のコードを実行しているとします:

checkAge minimumさて、コードの後半で、minimum関数がcheckAgeの値を18から18に更新するとします。

次に、次のコードを実行しているとします:

<code class="language-javascript">// 不纯
let minimum = 21;
const checkAge = (age) => age >= minimum;

// 纯
const checkAge = (age) => {
    const minimum = 21;
    return age >= minimum;
};</code>

同じ入力が与えられているものの、checkAge関数は異なる値に評価されます。

純粋な関数は、パラメーターとして提供される値以外の他の値に依存しないため、コードを簡単に移植できます。返品値が変更されないという事実により、純粋な関数がテストしやすくなります。

純粋な機能を一貫して書くことは、突然変異と副作用の可能性も排除します。

変異は機能プログラミングの大きな赤い旗であり、詳細を知りたい場合は、JavaScriptの可変割り当てと突然変異のガイドでそれらについて読むことができます。

機能を簡単に移植できるようにするには、機能が常に純粋であることを確認してください。

ルール2:変数を変更せずに保ちます

変数の宣言は、プログラマーが学習する最初のことの1つです。些細なことになりますが、機能的なプログラミングスタイルを使用する場合は非常に重要です。

機能プログラミングの重要な原則の1つは、変数が設定されると、プログラム全体でその状態のままになることです。

これは、コード内の変数の再割り当て/再件名が災害になる可能性のある最も簡単な例です。

<code class="language-javascript">checkAge(20); // false</code>
慎重に考えると、

の値は10と11の両方ではありません。 n

命令的なプログラミングにおける一般的なコーディングプラクティスは、次のコードを使用して値を増やすことです。

数学では、声明は非論理的です。なぜなら、両側から
<code class="language-javascript">checkAge(20); // true</code>
を減算すると、明らかに間違っている

が得られるからです。 x = x 1 xしたがって、Haskellでは、変数を値に割り当ててから別の値に再割り当てすることはできません。 JavaScriptでこれを達成するには、常に0 = 1を使用して変数を宣言するルールに従う必要があります。

constルール3:矢印関数を使用します

数学では、関数の概念は、あるセットのセットを別のセットにマッピングするという概念です。次の図は、左側に設定された値を右側に設定された値にマッピングする関数を示しています。

これは、矢印表記を使用して数学でそれを書く方法です:f:x→x²。これは、関数fが値xからx²をマップすることを意味します。

5 Ways to Make Your JavaScript More Functional この関数は、矢印関数を使用してほぼ同じ方法で記述できます。

JavaScriptで機能スタイルを使用する重要な機能は、通常の関数ではなく矢印関数の使用です。もちろん、これはスタイルに要約されます。通常の関数の代わりに矢印関数を使用しても、実際にはコードの「機能的」の程度には影響しません。

ただし、機能的なプログラミングスタイルを使用するときに適応するのが最も難しいことの1つは、各関数を出力へのマッピング入力として考える方法です。いわゆるプロセスはありません。矢印関数を使用すると、関数のプロセスをよりよく理解できることがわかりました。

矢印関数には暗黙の返品値があり、このマップを視覚化するのに役立ちます。
<code class="language-javascript">const n = 10;
n = 11; // TypeError: "Attempted to assign to readonly property."</code>

矢印関数の構造 - 特に暗黙の戻り値は、その構造が実際に「出力にマッピングされた」:

<code class="language-javascript">// 不纯
let minimum = 21;
const checkAge = (age) => age >= minimum;

// 纯
const checkAge = (age) => {
    const minimum = 21;
    return age >= minimum;
};</code>

特に矢印の関数を書くときに強調したいもう1つのことは、三元演算子を使用することです。あなたが三元演算子に慣れていない場合、それらはif...elseのインラインcondition ? value if true : value if falseステートメントです。

それらについての詳細は、javascriptで三党のオペレーターを使用する方法:迅速なヒントで読むことができます。

機能プログラミングで3成分演算子を使用する主な理由の1つは、elseステートメントの必要性です。プログラムは、元の条件が満たされていない場合は何をすべきかを知っている必要があります。たとえば、HaskellはA ステートメントが指定されている場合、エラーが返されます。 elseステートメントではなく、常に値を返す式であることです。これは、矢印の関数に特に役立ちます。これは、戻り値が存在することを確認し、出力マップへの画像入力を維持できることを意味するためです。声明と表現の間のニュアンスについて確信が持てない場合は、声明と表現に関するガイドは読む価値があります。 else

これらの2つの条件を説明するために、次のことは、三元演算子を使用した単純な矢印関数の例です。

if-else

関数は、

パラメーターの値に基づいて「eat」または「sleep」の値を返します。

<code class="language-javascript">checkAge(20); // false</code>
だから、要するに、コードをより機能的にするときは、次の2つのルールに従う必要があります。

action矢印表記を使用して関数の書き込みstate

ステートメントを三元演算子

に置き換えます
  • ルール4:for loop
  • if...elseを削除します
  • プログラミングで
を使用して反復コードを書くことが非常に一般的であることを考えると、それらを避けたいと言うのは奇妙に思えます。実際、Haskellが

ループ操作さえ持っていないことを最初に発見したとき、標準操作を実装する方法を理解するのに苦労しました。ただし、ループが機能プログラミングに表示されない理由はいくつかあり、ループを使用せずにあらゆるタイプの反復を実装できることをすぐに発見しました。

使用されていないforループがループされる最も重要な理由は、それらが可変状態に依存していることです。単純な合計関数を見てみましょう:for for forご覧のとおり、

ループ自体と

ループで更新される変数でforを使用する必要があります。

前述のように、これは通常、機能プログラミングの悪い実践です。これは、機能プログラミングのすべての変数が不可能であるためです。
<code class="language-javascript">checkAge(20); // true</code>

すべての変数が不変のコードを書きたい場合は、再帰を使用できます。 for forご覧のとおり、変数は更新されません。 let

私たちの間の数学者は、このコードのすべてが不要であることを明らかに知っているでしょう。しかし、これはループの変動性と再帰の違いを説明する素晴らしい方法です。 for ただし、特に配列を扱う場合、再帰は変動性問題の唯一の解決策ではありません。 JavaScriptには、変数を変更せずに配列内の値を反復する多くの組み込みの高次配列メソッドがあります。

たとえば、

アレイ内の各値に1を追加する必要があるとします。命令的な方法と

ループを使用して、私たちの関数は次のようになるかもしれません:

for ただし、JavaScriptの組み込み

メソッドを使用して、次のような関数を記述できます。
<code class="language-javascript">// 不纯
let minimum = 21;
const checkAge = (age) => age >= minimum;

// 纯
const checkAge = (age) => {
    const minimum = 21;
    return age >= minimum;
};</code>

map関数を見たことがない場合、それは間違いなくそれらについて知っておく価値があります - そして、特にあなたが本当に感覚を持っている場合、

などのJavaScriptのすべての組み込みの高次配列メソッドJavaScriptの関心における機能プログラミングの。それらについては、不変の配列方法:非常に明確なJavaScriptコードを書く方法で詳しく知ることができます。
<code class="language-javascript">checkAge(20); // false</code>

haskellにはまったくmapループがありません。 JavaScriptをより機能的にするには、再帰的で組み込まれた高次配列メソッドを使用して、filterループの使用を避けてください。

forルール5:spentation for型宣言を必要としないJavaScriptなどの言語でプログラミングする際のデータ型の重要性を忘れがちです。 JavaScriptで使用される7つのプリミティブデータ型は次のとおりです。

番号 文字列

boolean

    シンボル
  • bigint
  • 未定義
  • null
  • haskellは、タイプの宣言を必要とする強力な型型言語です。これは、機能の前に、Hindley-Milnerシステムを使用して、入力とデータ型出力を指定する必要があることを意味します。
  • 例:
  • これは、2つの数値(xとy)を一緒に追加する非常に単純な関数です。このような非常に単純な関数を含むすべての機能について、プログラムにデータ型を説明しなければならないのは少しばかげているように思えますが、これは最終的に機能がどのように機能するか、そしてそれが返されると予想されるものを示すのに役立ちます。これにより、特にコードがより複雑になった場合、コードのデバッグが容易になります。

宣言は次の構造に従います

JavaScriptを使用する場合、タイプの力は大きな問題になる可能性があります。これには、データ型の矛盾をバイパスするために使用できるさまざまなトリックがあります(

abuse

<code class="language-javascript">checkAge(20); // true</code>
)。最も一般的なヒントとそれらを回避する方法は次のとおりです。

接続。 「Hello」5は「hello5」として評価されますが、これは一貫していません。数値で文字列を連結したい場合は、「Hello」文字列(5)を記述する必要があります。

ブールステートメントと0。 javaScriptでは、

ステートメントの値0はfalseに相当します。これにより、数値データが0に等しいかどうかを確認することを無視する怠zyなプログラミング技術につながる可能性があります。

<code class="language-javascript">const n = 10;
n = 11; // TypeError: "Attempted to assign to readonly property."</code>

例:

<code class="language-javascript">// 不纯
let minimum = 21;
const checkAge = (age) => age >= minimum;

// 纯
const checkAge = (age) => {
    const minimum = 21;
    return age >= minimum;
};</code>

これは、数値が偶数であるかどうかを評価する関数です。 !シンボルを使用してn % 2の結果をブール値にキャストしますが、n % 2の結果はブール値ではなく、数(0または1)です。

このようなヒントは、一見賢く、書いたコードの量を減らしますが、機能プログラミングのタイプの一貫性ルールを破ります。したがって、この関数を書く最良の方法は次のとおりです。

別の重要な概念は、配列内のすべてのデータ値が同じタイプであることを確認することです。 JavaScriptはこれを強制しませんが、同じタイプがない場合、高次配列メソッドを使用する場合に問題を引き起こす可能性があります。
<code class="language-javascript">checkAge(20); // false</code>
たとえば、

すべての数値を配列内の倍増して返す製品関数は、次のタイプの宣言注釈で記述できます。

ここで、タイプ宣言は、関数の入力はタイプ数の要素を含む配列であるが、1つの数値のみを返すことを明確に示しています。タイプ宣言は、この関数の予想される入力と出力を明確に示しています。明らかに、配列に数字以上のものが含まれている場合、この関数は機能しません。

<code class="language-javascript">checkAge(20); // true</code>
haskellは強く型付けられた言語ですが、JavaScriptは弱く型付けされた言語ですが、JavaScriptをより機能的にするには、機能を宣言する前にタイプの宣言コメントを書いて、型強制ショートカットを避ける必要があります。

また、ここでは、タイプの一貫性を強制するJavaScriptに強くタイプされた代替品が必要な場合は、TypeScriptに頼ることができることをここで言及する必要があります。

結論

全体として、次の5つのルールは、機能コードの実装に役立ちます。 機能を維持

純粋

  • constを使用して、常に変数と関数を宣言します。
  • 関数に
  • 矢印表記を使用します。
  • loopを使用しないでください。
  • タイプ宣言の注釈を使用し、タイプの強制ショートカットを避けます。 for これらのルールは、コードが純粋に機能的であることを保証するものではありませんが、大部分はより機能的に機能し、よりクリーンでより明確で、テストしやすくします。
  • これらのルールができる限りあなたを助けることを本当に願っています!私たちは両方とも機能的プログラミングの大ファンであり、プログラマーを使用することを強くお勧めします。
機能的なJavaScriptをより深く掘り下げたい場合は、「Frisby教授による機能プログラミングの十分なガイドのほとんどを読むことを強くお勧めします。 Haskellを学びたい場合は、Try Haskell Interactiveチュートリアルを使用して、優れた本Learn Haskellを読むことをお勧めします。

JavaScript機能プログラミングについてよく尋ねる質問

JavaScriptの機能プログラミングとは何ですか? 関数プログラミングは、計算を数学機能の評価として扱い、状態の変化と可変データを回避するプログラミングパラダイムです。 JavaScriptでは、一流の市民として機能を使用し、副作用を回避することが含まれます。

JavaScriptのファーストクラスの機能とは何ですか? JavaScriptのファーストクラス関数は、関数が他の変数と同じように扱われることを意味します。それらは変数に割り当てられ、パラメーターとして他の関数に渡され、他の関数から値として返すことができます。

機能プログラミングの不変性は何ですか? 不変性とは、オブジェクトが作成されると、変更できないことを意味します。 JavaScriptの機能プログラミングのコンテキストでは、これは変数を初期化した後の変更変数またはデータ構造を回避することを意味します。

高次関数とは何ですか? 高次関数は、他の関数をパラメーターとして取得する関数または結果として関数を返す関数です。機能の組み合わせをサポートしているため、モジュラーコードと再利用可能なコードを簡単に作成できます。

JavaScriptで機能的なプログラミングを促進するライブラリ/フレームワークはありますか? はい、一部のライブラリとフレームワーク(RamdaやLodashなど)は、JavaScript機能プログラミングの概念をサポートするユーティリティと機能を提供します。機能的なプログラミングプラクティスを簡素化および強化するのに役立ちます。

以上がJavaScriptをより機能的にする5つの方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。