2013-08-12 17 views
13

JavaScriptは、すでに設定値を持っているか、メソッドを持つオブジェクトである引数で記述されていることがあります。例えば、このjQueryの例を見てみましょう:JavaScriptでの匿名関数の引数の受け渡し

$(".selector").children().each(function(i) { 
    console.log(i); 
}); 

iをログに記録するとき、あなたはjQueryのeach方法でセレクタの子どもたちを見ているとき、その反復にあるものiの値になるだろう。

これは例をNode.jsの乗り:

http.createServer(function(request, response) { 
    response.writeHead(200, {"Content-Type": "text/plain"}); 
    response.write("Hello World"); 
    response.end(); 
}).listen(8888); 

あなたがrequestresponseが渡されると、彼らが行動することができ、独自のメソッドが含まれていることをここで見ることができます。

私には、このメソッドには、既にメソッドがアタッチされている2つの引数を持つ関数createServerに関数が渡されているようです。

私の質問は、マルチパートのいずれかになります。これらの引数から来るのか

  1. これらが単なる関数である場合、他の関数と同様に動作する引数をどのように受け取るのですか?
  2. このような独自の引数をとる関数を作成するにはどうすればよいですか?
  3. これはクロージャの力を使用しますか?

答えて

13

私には、これはメソッドがすでにそれらに接続されている2つの引数を持つcreateServer関数に関数を渡しているようです。

いいえ、彼らは2つの引数をとるcreateServerに関数を渡していました。これらの機能は、後で呼び出し側が中に入れ何の引数で呼び出されます例:。このはあなたがbindメソッドを使用することができます欲しいものない場合

function caller(otherFunction) { 
    otherFunction(2); 
} 
caller(function(x) { 
    console.log(x); 
}); 

は、2

より高度な印刷されますすべての関数に属します。指定された引数がすでにバインドされた新しい関数が作成されます。例えば:

caller(function(x) { 
    console.log(x); 
}.bind(null, 3); 
}); 

これで3が出力され、匿名関数に渡された引数2は未使用の名前のない引数になります。

とにかく、それは密集した例です。バインディングの仕組みを理解するためにリンクされたbindのドキュメントを参照してください。

+0

しかし、どのように 'し' request'とだからそれは、クロージャを使用して匿名関数へ

var a = 'hello'; // Crockford (function(a){alert(a)}(a)); // Others (function(a){alert(a)})(a); 

をパラメータを渡す例ですレスポンスは私のノードの例では既にメソッドがありますか?これは私には意味がありません。 – Sethen

+0

@SethenMaleno:「既に」ということはどういう意味ですか?関数が呼び出されるまで、パラメーターには値はありません。 – Bergi

+1

@SethenMaleno 'request'と' response'は単に 'createServer'メソッドのパラメータです。そのメソッドが実際に呼び出されると、操作可能な要求と応答を表す2つのオブジェクトが渡されます。パラメータを宣言するだけで、関数が期待しているものが設定されます。機能が呼び出されたときに魔法が発生する – Ian

0

はい、引数として関数を渡しています。もちろん、渡す関数には独自の引数があります。

そして、これらの引数は

http.createServer関数を受け入れる、それが機能を持っているか月の引数ことを知っているだろうなど、自分自身のメソッドを持っている可能性のあるオブジェクトを含む何もすることができます。これを行う1つの方法は、渡された関数のargumentsプロパティを確認することです。または、APIの開発者が実際の要素を使用している可能性があります。

この関数の作者は、引数として期待されるものを知り、api documentationにそれを記録します。

3

のは、例えば$.eachを見てみましょう。これは、最初のブロック内の行(ある

return $.each.call(this, callback /* this is your function */, args /* which is an additional thing people rarely use*/) 

each: function (obj, callback, args) { 
    var value, 
    i = 0, 
     length = obj.length, 
     isArray = isArraylike(obj); 

    if (args) { 
     if (isArray) { 
      for (; i < length; i++) { 
       value = callback.apply(obj[i], args); 

       if (value === false) { 
        break; 
       } 
      } 
     } else { 
      for (i in obj) { 
       value = callback.apply(obj[i], args); 

       if (value === false) { 
        break; 
       } 
      } 
     } 

     // A special, fast, case for the most common use of each 
    } else { 
     if (isArray) { 
      for (; i < length; i++) { 
       value = callback.call(obj[i], i, obj[i]); 

       if (value === false) { 
        break; 
       } 
      } 
     } else { 
      for (i in obj) { 
       value = callback.call(obj[i], i, obj[i]); 

       if (value === false) { 
        break; 
       } 
      } 
     } 
    } 

    return obj; 
} 

これは、同じよう

$(".selector").children().each(function(i) { 
    console.log(i); 
}); 

から呼び出されます)あなたが見たい

callback.call(obj[i], i, obj[i]); 

コールバックを呼び出してオブジェクトをコンテキストとして渡しているため、ループ内でthisを使用することができます。次に、iの繰り返しと、コンテキストと同じオブジェクトが両方とも引数としてコールバックに送信されます。それは魔法のようなものです。あなたがソースコードを見るまで。

0

あなたはcreateServerのコードを見た場合、それはこのような何かになりたい:

function createServer (handleRequestAndResponseFunction) { 
    handleRequestAndResponseFunction(actualRequest, actualReponse); 
} 

[OK]を、いや、それはないだろうが、それは簡単な例です。 createServerは2つの引数を受け入れるfunctionを受け取ります。

より現実的に言えば、2つの引数の関数を渡すと、ミドルウェアの処理と必要な処理を行い、その関数を呼び出して、独自の要求と応答変数を渡します。

0

は、ここでは、無名関数(それは実際にすべてのあなたがそれを書いた方法によって異なります)

関連する問題