1 関数カリー化とは何ですか?コンピュータ サイエンスにおいて、 どういう意味ですか?簡単に言えば、カリー化は複数のパラメータを持つ関数を変換するために使用される手法です。 例えば: // これは3つのパラメータを受け入れる関数です。const add = function(x, y, z) { x + y + zを返す } これを変換すると、次のような関数が得られます。 // 単一のパラメータを受け入れる const curryingAdd = function(x) { // 残りのパラメータを受け入れる関数を返します return function(y, z) { x + y + zを返す } } これによって何が変わるのでしょうか?通話から比較: // 追加を呼び出す 加算(1, 2, 3) // curryingAdd を呼び出す カレー化追加(1)(2, 3) // もっとわかりやすく見てみましょう。これはconst fn = curryingAdd(1)と同等です。 関数(2, 3) ご覧のとおり、変換された関数はバッチでパラメータを受け入れることができます。その有用性については後で説明するので、まずこの点に留意してください。 fn( 次のように: const curryingAdd = function(x) { 関数(y)を返す{ 関数(z)を返す{ x + y + zを返す } } } // curryingAdd(1)(2)(3) を呼び出す // つまり、const fn = curryingAdd(1) 定数fn1 = fn(2) fn1(3) 上記の 2 つの変換プロセスは関数カリー化です。 簡単に言えば、マルチパラメータ関数 では、関数をカリー化するためにそこまで苦労する意味は何でしょうか? 2 カレーの役割と特徴2.1 パラメータの再利用職場で遭遇する要件:正規表現を使用して電話番号、メールアドレス、ID カードなどの合法性をチェックする そこで、検証関数を次のようにカプセル化します。 /** * @description 正規表現検証文字列を渡します* @param {RegExp} regExp 正規表現オブジェクト* @param {String} str 検証する文字列* @return {Boolean} 検証に合格したかどうか*/ 関数 checkByRegExp(regExp, str) { regExp.test(str) を返す } 多数の携帯電話番号とメールアドレスを検証したい場合は、次のように呼び出します。 // 電話番号を確認します checkByRegExp(/^1\d{10}$/, '15152525634'); checkByRegExp(/^1\d{10}$/, '13456574566'); checkByRegExp(/^1\d{10}$/, '18123787385'); // メールをチェック checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, '[email protected]'); checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, '[email protected]'); checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, '[email protected]'); 問題はなさそうだが、まだ改善の余地がある
関数のカリー化を使用してこれを改善してみましょう。 // 関数をカリー化する function checkByRegExp(regExp) { 関数(str)を返す{ regExp.test(str) を返す } } したがって、異なる通常のオブジェクトを渡すと、異なる機能を持つ関数を取得できます。 // 電話番号をチェック const checkPhone = curryingCheckByRegExp(/^1\d{10}$/) // メールをチェック const checkEmail = curryingCheckByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/) 携帯電話と電子メール アドレスを確認するためのコードがよりシンプルで読みやすくなりました。 // 電話番号を確認する checkPhone('15152525634'); 電話番号を確認してください('13456574566'); 電話番号を確認してください('18123787385'); // メールを確認する checkEmail('[email protected]'); メールアドレスを確認してください('[email protected]'); メールアドレスを確認してください('[email protected]'); これはパラメータの再利用です。特定の関数を持つ関数を直接呼び出すには、最初のパラメータ ユニバーサル関数 ( 同じルールが繰り返し使用される場合(携帯電話のパラメータの検証など)、コードの重複が発生することがあります。カリー化により重複を排除し、パラメータの再利用の目的を達成できます。 カリー化の重要な考え方:適用範囲を狭め、適用性を高める 2.2 早期復帰
今回は、各ブラウザのバージョンと互換性のあるコードを記述します。 /** * @説明: * @param {object} element DOM要素オブジェクト* @param {string} type イベントタイプ* @param {Function} fn イベント処理関数* @param {boolean} isCapture キャプチャするかどうか* @return {void} */ 関数 addEvent(要素, タイプ, fn, isCapture) { ウィンドウにイベントリスナーを追加する場合 要素.addEventListener(type, fn, isCapture) } それ以外の場合 (window.attachEvent) { 要素.attachEvent("on" + タイプ, fn) } } イベントリスナーの追加には カレー作り: 関数curryingAddEvent() { ウィンドウにイベントリスナーを追加する場合 関数(要素、タイプ、fn、isCapture)を返す{ 要素.addEventListener(type, fn, isCapture) } } それ以外の場合 (window.attachEvent) { 関数(要素、型、関数)を返す{ 要素.attachEvent("on" + タイプ, fn) } } } const addEvent = curryingAddEvent() // 即時実行関数を使用して上記のコードをマージすることもできます const addEvent = (function curryingAddEvent() { ... })() ここで取得する これは早期リターンまたは早期確認です。カリー化後、関数はいくつかのタスクを事前に処理し、他のタスクを処理する関数を返すことができます。 さらに、 論理的には、次のように変更できます。 mode = window.addEventListener ? 0 : 1 とします。 関数 addEvent(モード、要素、タイプ、fn、isCapture) { モード === 0 の場合 要素にイベントリスナーを追加します(type、fn、isCapture); } それ以外の場合 (モード === 1) { 要素.attachEvent("on" + タイプ、fn); } } // この方法では、カリー化後に最初にパラメータを受け入れることができます。 function curryingAddEvent(mode) { モード === 0 の場合 関数(要素、タイプ、fn、isCapture)を返す{ 要素.addEventListener(type, fn, isCapture) } } それ以外の場合 (モード === 1) { 関数(要素、型、関数)を返す{ 要素.attachEvent("on" + タイプ, fn) } } } もちろんこれを変更する必要はありません。 2.3 遅延実行実際、遅延実行は、上記の通常の検証とイベント リスニングの例にすでに反映されています。 返された関数はすぐには実行されず、呼び出しを待機します。 3 一般的なカリー化ユーティリティ関数のカプセル化#上記では、カリー化のために元の関数を手動で変更し、 関数をカリー化するたびに、基礎となる関数を手動で変更する必要がありますか?もちろん違います 一般的なカリー化ユーティリティ関数をカプセル化することができます(インタビュー用の手書きコード) /** * @description: 関数をカリー化するためのツール関数* @param {Function} fn カリー化される関数* @param {array} args すでに受け取った引数のリスト* @return {Function} */ const カリー化 = function(fn, ...args) { // fn に必要なパラメータの数 const len = fn.length // 残りのパラメータを受け取る関数を返す return function (...params) { // 受信したパラメータリストと新しく受信したパラメータリストを連結する let _args = [...args, ...params] // 受け取ったパラメータの数が足りない場合は、残りのパラメータを受け取るための新しい関数を返し続けます if (_args.length < len) { currying.call(this, fn, ..._args) を返します } // すべてのパラメータを受け取ったら、元の関数を呼び出します。 return fn.apply(this, _args) } } このカリー化ユーティリティ関数は、いくつかのパラメータを受け取り、残りのパラメータを待機する新しい関数を返し、必要なパラメータがすべて受け取られるまで再帰的に実行し、 今では、関数をカリー化するために元の関数を手動で変更する必要がなくなりました。 // ツール関数を直接使用して、電話番号とメールアドレスを確認する関数を返します。const checkPhone = currying(checkByRegExp(/^1\d{10}$/)) const checkEmail = カリー化(checkByRegExp(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/)) しかし、上記のイベント監視の例は、このユーティリティ関数を使用してカリー化することはできません。理由は前述のとおりです。その条件はグローバルコンテキストから直接取得されるため、非常に特殊です。外部から条件を渡すように変更すると、ユーティリティ関数のカリー化を使用できます。もちろん、これは必要ありません。元の関数を直接変更する方が直接的で読みやすくなります。 4 要約と補足
以下もご興味があるかもしれません:
|
<<: MySQLのMVCCマルチバージョン同時実行制御の実装
>>: CSS を使用して等アスペクト比のアダプティブ コンテナを実装する方法
この記事は、CentOS 7の詳細なインストールチュートリアルを参考のために記録します。具体的な内容...
序文この記事では主にMySQLでよく使われるツールに関する関連コンテンツを紹介し、皆さんの参考と学習...
成果を達成する実装コードhtml <ヘッダー> <h1><em>...
1. 外部キーの設定方法1. MySQL では、2 つのテーブルを関連付けるために、外部キー (FO...
目次Oracle 分離レベルMySQL 分離レベル要約する多くの読者は、MySQL のトランザク...
表は以下のとおりです。 Unity が読み取って呼び出すときのコード: データベース内の別のテーブル...
Vueのコントロール商品数量コンポーネントのカプセル化と使用は参考までに。具体的な内容は以下のとお...
MYSQL のフィールドのデータの一部をバッチで置き換えます。具体的な導入は次のとおりです。 1....
この記事は主に、Nginx のフォワード プロキシとリバース プロキシ、および負荷分散機能の設定コー...
1. システム環境yum updateアップグレード後のシステムバージョンは[root@yl-web...
Web テーブルの構造マークアップについて説明する前に、いくつかの画像を見てみましょう。 HTML ...
目次1. 魔法の拡張演算子1. 配列をコピーする2. 配列を結合する3. オブジェクトを展開する2....
(P4) Web 標準は一連の標準で構成されています。中心となる概念は、Web ページの構造、スタイ...
目次1. コア1. Domノードを取得する2. ノードの更新2.1 実践演習3. Domノードを削除...
目次1. JavaScriptを記述する場所2. JavaScriptでよく使われる入力文と出力文1...