2014-01-14 14 views
5

私は"Hey Underscore, You're Doing it Wrong" JavaScript talk(4:15)でこの構文を見つけました。私はそれが何を意味するのか知りたい。 JavaScriptでJavaScriptの関数宣言で.autoCurry()を宣言するとどうなりますか?

var add = function(x,y){ 
    return x + y; 
}.autoCurry();//What is happening in this line. 
+3

その話、 *本当に*先進的な素材です。 – Pointy

+1

はい、その話の4:12で、彼は明示的に彼がFunctionプロトタイプに "autoCurry"を追加したと言います。 – Pointy

+0

'autoCurry()'は以前の 'curry()'に名前が変更されています。 – falconepl

答えて

0

、関数インスタンス式は:

function name(arg1, arg2, ...) { /* code */ } 

は、関数オブジェクトへの参照に機能し、結果を作成します。したがって、.autoCurry()は、そのオブジェクトのプロパティへの参照であり、明らかに関数であると見なされます。

あなたが見ている例では、関数プロトタイプオブジェクトに "autoCurry"を追加するコードがいくつかあると思います。こうすることで、すべての関数オブジェクトはその関数に "autoCurry"プロパティとしてアクセスできます。

+0

お返事ありがとうございました – Taimoor

1

まあ、私は、まさにautoCurryが...何をしているのかを教えてくれ...しかし、私はあなたを伝えることができることはこれであることができません:彼らはFunctionコンストラクタのプロトタイプを変更した

  1. Function.prototype.autoCurry = function() { };
    そのページで行ったすべての新しい機能は、このメソッドのプロパティの1つとしてこのメ​​ソッドにアクセスできるようになりました。
    var myFunc = function() { return true; }; myFunc.autoCurry();

  2. JSをうまく組み合わせることができます。
    var myObj = { run : function() { } }, result = myObj.run();は、myObjを気にしない限り、
    var result = { run : function() { } }.run();と同じです。

    だから、

  1. に(最後のものをあなたは機能を作成している、とすぐそれが作成されますよう、あなたがそれにメソッドを実行している、とそのメソッドのreturn文チェーン)が変数に保存されています。今

、カリー化はあなたが必要な引数の一部だけでそれを呼び出すことができます機能を取り、他の関数でラップの形態です。

function add_two_numbers = function(x、y){return x + y; }

カリー化は、あなたがこれを行うことができるようになる:あなたの新しいタイトルについては

var save_x_for_later = curry(add_two_numbers), 
    save_y_and_add = save_x_for_later(3), 
    result = save_y_and_add(5); 

result; // 8 

、答えは以下の通りです: あなたはエラーがあなたの顔にスローされます: .autoCurry()はの一部ではありません言語。 それは、手で、書かれた、とあなたは多くの関数型プログラミングを行っていない場合、私はカリー化の実装に入ることができますが、周りにあなたの頭をラップするために多くのものがあります

Function.prototype.autoCurry = function() { }として Function.prototypeに置かれましたまたは「ラムダ」が頭を掻く言葉である場合。

+0

あなたの答えはありがとうございました。非常に有益... – Taimoor

8

最初に、カレーとオートカレーが実際に何をするかを見てみましょう。私はこれらの2つの関数のソースに注釈を付けました(元々はwuで見つかりました。JSライブラリ):すなわち

//// 
    // Type: 
    // 
    // ((a,b, ... c) -> d) -> a -> b -> ... -> c -> d 
    // 
    // Example: 
    // 
    // function add(a, b) { return a + b; } 
    // add2 = curry(add, 2) 
    // add2(3) 
    // // 5 
    function curry(fn /* variadic number of args */) { 
    var args = Array.prototype.slice.call(arguments, 1); 
    function f() { return fn.apply(this, args.concat(toArray(arguments))); } 
    return f; 
    } 

    //// 
    // Example: 
    // 
    // function add(a, b) { return a + b; } 
    // autoCurry(add); 
    // 
    // add(2)(3)      
    // // 5 
    // 
    // add(2, 3) 
    // // 5 
    function autoCurry(fn, numArgs) { 
    numArgs = numArgs || fn.length; 
    function f() { 
     if (arguments.length < numArgs) 
     { 
     return numArgs - arguments.length > 0 ? 
     autoCurry(curry.apply(this, [fn].concat(toArray(arguments))), 
     numArgs - arguments.length) : 
     curry.apply(this, [fn].concat(toArray(arguments))); 
     } 
     else 
     { 
     return fn.apply(this, arguments); 
     } 
    } 
    f.toString = function() { return fn.toString(); }; 
    f.curried = true; 
    return f; 
    } 

autoCurry(add) 

は、2つの引数を取り、番号を返す関数を取り、そして単一の引数を取り、機能Bを返す関数Aを返しますBは、単一の引数を取り、数を返す関数である:

add(1) -> returns a function add1(), which itself takes a single argument. 

次へ]を、その話でスピーカーは、以下のん:

Function.prototype.autoCurry = function(n) { return autoCurry(this, n); } 

var add = function(x,y){ 
    return x + y; 
}.autoCurry(); 

がするのと同じ効果がありますように、これは、単に任意の機能(自己)にautoCurry法を適用:あなたはJavaScriptで初心者なら

var add = function(x,y) { return x + y; }; 
add = autoCurry(add) 
+0

ここで定義された 'toArray'関数が必要です。定義された 'カレー'関数、すなわちfunction toArray(args){return [] .slice.call(args); } ' –

関連する問題