目次
JavaScript関数カリーリングの詳しい説明
JavaScript 関数カリー化の詳細説明
ホームページ ウェブフロントエンド jsチュートリアル JavaScript関数のカリー化の詳細説明

JavaScript関数のカリー化の詳細説明

Feb 27, 2017 pm 02:29 PM

JavaScript関数カリーリングの詳しい説明

Baidu百科事典のカリーリングの説明: コンピュータサイエンスにおいて、カリーリングとは、複数のパラメーターを受け入れる関数を、単一のパラメーターを受け入れる関数(元の関数、最初の引数) を受け取り、残りの引数を受け入れて結果を返す新しい関数を返します。この手法は論理学者のハスケル・カリーにちなんでクリストファー・ストレイチーによって命名されましたが、発明したのはモーゼス・シュンフィンケルとゴットロブ・フレーゲでした。
上記の説明を読んで、カリー化がどのような関数であるかをすぐに理解できる人は多くないと思います。平たく言えば、関数カリー化の主な目的は、関数パラメータを削減し、いくつかの固定パラメータをプライベート化することです。以下は、関数カリー化の原理を説明するために円の面積を計算するための非常に単純なコードを示しています:

//circle函数,接受半径r和πfunction circle(r,p){
    //计算半径为r的圆的面积
    var area=p*r*r;    return area;
}/*
 * 通过函数柯里化来简化circle函数,只传入半径就能计算出面积
 * 不管怎么样,π是不会变的,因此我们将他写死,不需要外部调用传入
 */function curryCircle(r){
    var p=3.14;    var area=p*r*r;    return area;
}
ログイン後にコピー
ログイン後にコピー

このコードは奇妙だと思うかもしれませんが、これが関数カリー化の本当の姿です。もちろん、上記のコードは非常に小さな例にすぎません。実際の関数カリー化はもう少し悪質です。以下でより一般的な例について説明します。 π が一意ではないと仮定すると (たとえば、3 種類の π がある)、円の面積を計算する式の π はさまざまなシナリオに応じて変化します。現時点では、それを直接記述することはできませんが、π を構成する必要があります。さまざまな環境に応じて:

//circle函数,接受半径r和π
function circle(r,p){
    //计算半径为r的圆的面积
    var area=p*r*r;    
    return area;
}
//针对circle函数的柯里化函数function curry(fn,p){
    var finalMethod=function(r){
        var result=fn(r,p);        return result;
    }    return finalMethod;
}
//我们有3种不同的πvar curryCircle1=curry(circle,1.14);
var curryCircle2=curry(circle,2.14);
var curryCircle3=curry(circle,3.14);
//输出:4.56  8.56  12.56
console.log(curryCircle1(2),curryCircle2(2),curryCircle3(2));
ログイン後にコピー

はい ご覧のとおり、curry メソッドは最も基本的な Circle メソッドをカプセル化し、設定された p パラメータ (π) を保存し、finalMethod メソッドを返すため、最終的に FinalMethod を呼び出すときに必要なのは、パラメータ r (半径) を渡します。関数カリー化の助けを借りて、円の面積を計算するための 3 つの簡素化された方法があります。上に示した関数カリー化は、円の面積の計算にのみ適用できます。今回は、より一般的なカリー化関数を作成します。

function curry(fn){
    //第一个参数是基础执行方法,slice切除
    var args=Array.prototype.slice.call(arguments,1);    //直接返回匿名函数
    return function(){
        //slice新参数以便能调用concat
        var innerArgs=Array.prototype.slice.call(arguments);        //将配置的参数和新传入的参数合并
        var finalArgs=args.concat(innerArgs);        return fn.apply(null,finalArgs);
    };
}
ログイン後にコピー
ログイン後にコピー

curry() 関数の主な仕事は、返された関数のパラメーターを並べ替えることです。 Curry() の最初のパラメータはカリー化される関数であり、他のパラメータは渡される値です。最初のパラメータ以降のすべてのパラメータを取得するには、引数オブジェクトでslice()メソッドが呼び出され、パラメータ1が渡されて、返された配列に2番目のパラメータ以降のすべてのパラメータが含まれていることを示します。 args 配列には、外部関数からの引数が含まれます。内部関数では、すべての受信パラメータを格納するために innerArgs 配列が作成されます (slice() が再度使用されます)。外部関数と内部関数を格納するパラメーター配列を取得したら、 concat() メソッドを使用してそれらを FinalArgs にマージできます。最後に apply() を使用して結果を関数に渡します。これにより、一般的な関数のカリー化が実現されます。この時点でまだエネルギーが残っている場合は、jQuery で使用される関数のカリー化を紹介します。
メソッドをカリー化するとき、関数をラップするようにカリー化に指示するために fn を渡す必要さえありません。プロトタイプを通じて関数とカリー化を直接バインドできます:

Function.prototype.curry=function(){
    //利用原型的便利,我们可以直接通过this引用到方法
    var fn=this;    var args=Array.prototype.slice.call(arguments);    return function(){
        var arg=0;        //循环校验先前传入的参数和新传入的参数是否有差别
        for(var i=0;i<args.length && arg<arguments.length;i++){            if(args[i]===undefined){
                args[i]=arguments[arg++];
            }
        }        return fn.apply(this,args);
    };
};
ログイン後にコピー
ログイン後にコピー

前とは異なり、これを通じてメソッド参照を取得します。したがって、関数をカリーにする必要がある場合は、次のように記述するだけで済みます。

var delay=setTimeout.curry(undefined,10);
ログイン後にコピー
ログイン後にコピー

lay は、事前に 10 ミリ秒の遅延が設定されている setTimeout 関数です。パラメータ設定の保存には引き続き args を使用しますが、今回は違いがあります。args と引数の違いが for ループ内でチェックされ、この判断に基づいてパラメータの結合が完了します。したがって、curry に渡されるパラメータは完全なパラメータである必要があります (つまり、未定義の値を渡す必要があります)。最後に、fn を渡す必要のないカリー化メソッドを実装しました。

JavaScript 関数カリー化の詳細説明

Baidu 百科事典によるカリー化の説明: コンピューターサイエンスにおいて、カリー化とは、複数のパラメーターを受け入れる関数を、単一のパラメーター (元の関数の最初のパラメーター) を受け入れる関数に変換することです。 1 つのパラメータを受け取り、残りのパラメータを受け入れて結果を返す新しい関数を返します。この手法は、モーゼス シュンフィンケルとゴットロブ フレーゲによって発明されましたが、論理学者のハスケル カリーにちなんでクリストファー ストラチーによって命名されました。
上記の説明を読んで、カリー化がどのような関数であるかをすぐに理解できる人は多くないと思います。平たく言えば、関数カリー化の主な目的は、関数パラメータを削減し、いくつかの固定パラメータをプライベート化することです。以下は、関数カリー化の原理を説明するために円の面積を計算するための非常に単純なコードを示しています:

//circle函数,接受半径r和πfunction circle(r,p){
    //计算半径为r的圆的面积
    var area=p*r*r;    return area;
}/*
 * 通过函数柯里化来简化circle函数,只传入半径就能计算出面积
 * 不管怎么样,π是不会变的,因此我们将他写死,不需要外部调用传入
 */function curryCircle(r){
    var p=3.14;    var area=p*r*r;    return area;
}
ログイン後にコピー
ログイン後にコピー

このコードは奇妙だと思うかもしれませんが、これが関数カリー化の本当の姿です。もちろん、上記のコードは非常に小さな例にすぎません。実際の関数カリー化はもう少し悪質です。以下でより一般的な例について説明します。 π が一意ではないと仮定すると (たとえば、3 種類の π がある)、円の面積を計算する式の π はさまざまなシナリオに応じて変化します。現時点では、それを直接記述することはできませんが、π を構成する必要があります。さまざまな環境に応じて:

//circle函数,接受半径r和πfunction circle(r,p){
    //计算半径为r的圆的面积
    var area=p*r*r;    return area;
}//针对circle函数的柯里化函数function curry(fn,p){
    var finalMethod=function(r){
        var result=fn(r,p);        return result;
    }    return finalMethod;
}
//我们有3种不同的π
var curryCircle1=curry(circle,1.14);
var curryCircle2=curry(circle,2.14);
var curryCircle3=curry(circle,3.14);
//输出:4.56  8.56  12.56
console.log(curryCircle1(2),curryCircle2(2),curryCircle3(2));
ログイン後にコピー

可以看到,curry方法通过封装最基础的circle方法,同时保存设置好的p参数(π),并返回一个finalMethod方法,这样我们最终调用finalMethod时就只需要传入参数r(半径)就可以完成。借助函数柯里化,我们拥有了三个简化的计算圆面积方法。上面展示的函数柯里化只能适用于圆面积的计算,这次我们编写一个更通用的柯里化函数:

function curry(fn){
    //第一个参数是基础执行方法,slice切除
    var args=Array.prototype.slice.call(arguments,1);    //直接返回匿名函数
    return function(){
        //slice新参数以便能调用concat
        var innerArgs=Array.prototype.slice.call(arguments);        //将配置的参数和新传入的参数合并
        var finalArgs=args.concat(innerArgs);        return fn.apply(null,finalArgs);
    };
}
ログイン後にコピー
ログイン後にコピー

curry()函数的主要工作就是将被返回函数的参数进行排序。Curry()的第一个参数是要进行柯里化的函数,其他参数是要传入的值。为了获取第一个参数之后的所有参数,在arguments对象上调用了slice()方法,并传入参数1表示被返回的数组包含从第二个参数开始的所有参数。然后args数组包含了来自外部函数的参数。在内部函数中,创建了innerArgs数组用来存放所有传入的参数(又一次使用了slice())。有了存放来自外部函数和内部函数的参数数组后,就可以使用concat()方法将他们合并成finalArgs。最后使用apply()将结果传递给该函数。这样就实现了一个通用的函数柯里化。如果到这此还有余力的读者可以接着往下看,我们将要介绍jQuery中使用的函数柯里化。
在针对某个方法进行柯里化时,我们甚至不用传入fn来告诉柯里化来包装我们的函数,我们可以通过原型直接将函数和柯里化绑定:

Function.prototype.curry=function(){
    //利用原型的便利,我们可以直接通过this引用到方法
    var fn=this;    var args=Array.prototype.slice.call(arguments);    return function(){
        var arg=0;        //循环校验先前传入的参数和新传入的参数是否有差别
        for(var i=0;i<args.length && arg<arguments.length;i++){            if(args[i]===undefined){
                args[i]=arguments[arg++];
            }
        }        return fn.apply(this,args);
    };
};
ログイン後にコピー
ログイン後にコピー

与之前不同,我们通过this引用获取了方法引用,这样当我们需要将某个函数柯里化时,只要这样写就可以:

var delay=setTimeout.curry(undefined,10);
ログイン後にコピー
ログイン後にコピー

delay就是一个已经被提前设定了10毫秒延迟的setTimeout函数。我们仍然通过args来保存参数配置,不过这次有点区别:在for循环内部会校验args和arguments的区别,以此判断来完成参数拼接。所以传给curry的参数必须是完整参数(即意味着不传的值要传入undefined)。最终我们实现了一个不需要传入fn的柯里化方法。

 以上就是详解JavaScript函数柯里化 的内容,更多相关内容请关注PHP中文网(www.php.cn)!


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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

See all articles