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 を使用して等アスペクト比のアダプティブ コンテナを実装する方法
例:本日、前回のオフィスコラボレーションプラットフォーム実験の続きをしていたところ、仮想マシンは以前...
序文Web ページを作成するときに、次のような状況に遭遇することはよくあります。 <本文>...
目次序文LEDトリガー探索を始めるLEDデバイス登録LEDディレクトリ類推によって理解するクラスディ...
1. ホットリンクの原則1.1 Webページの準備Web ソース ホスト (192.168.153...
1. なぜこの記事を書くのですか?重複リクエストの処理に関する記事をたくさん読んだことがあるでしょう...
ディスク クォータは、コンピューター内の指定されたディスクのストレージ制限です。つまり、管理者はユー...
まず、バックグラウンドから来るデータをシミュレートしてみましょう。ここでは、コードをわかりやすくする...
この記事の例では、参考までに簡単な虫眼鏡効果を実現するためのjsの具体的なコードを共有しています。具...
/******************** * キャラクターデバイスドライバー**********...
目次CentOS rpm のインストールと Nginx の設定導入rpm パッケージのインストールサ...
方法 1: スクリプト方式を使用する:共通ヘッダー ファイル head.js または共通フッター フ...
目次プロジェクトの作成プロジェクト構造メイン.jsアプリ.vue:設定コンポジションAPI参照反応的...
v-for タグにキーが追加されていない場合。 <!DOCTYPE html> <...
Baiduで検索しました。 。 chcp コマンドを使用して、cmd の文字エンコーディングを 65...
SQL Server のバッチコメントバッチ注釈Ctrl + (K, C): Ctrlキーを押しなが...