1

私はと呼ばれる単純なオブジェクトを持っていますがEntry、それはつい最近までいくつかの基本的なプロパティしか持っていませんでした。特定のイベント中に、C#コードに存在するAPIに対してこれらのオブジェクトに対してRESTアクションを実行します。つい最近まで、これはうまくいきました。私の小さなリクエストサービスを使用して、これらのオブジェクトをAJAXリクエストの本文にPOSTまたはPUTします。これは、次のように終了します。

$.ajax(url, 
{
    type:method,
    headers:headers,
    data:options.data, //there is an instance of Entry in options.data
    timeout: this.timeoutLength
});

最近、エントリに関数を追加しました。

function Entry(foo, bar){
    this.foo = foo;
    this.bar = bar;
    this.doStuff = function(){ ... } //added this code
}

関数を追加しましたが、その使用の背後にあるユーザーストーリーに再度疑問を呈したため、ブラウザーに戻って更新し、さらにいくつかのテストを実行しました。どこでも関数を呼び出さなくてdoStuffも、その効果が見られました。

の本文を単純なアラートに置き換えましdoStuffた。確かに、Entryオブジェクトを使用してAJAXリクエストと呼ばれる舞台裏で何かを行うたびに、アラートメッセージが表示されました。なぜ世界でこれが起こっているのですか?なぜdoStuff私に言わずに呼ばれるのですか?

4

1 に答える 1

1

編集:tldr; Ajaxは、オブジェクトをシリアル化するときに、オブジェクト内のすべての関数を呼び出します。理由が気になる場合は、以下をお読みください。

スタックトレースを逆方向にたどることができるまで、これは私を少し夢中にさせました。関数doStuff jquery-1.7.1.jsによって呼び出されていたようです$.ajax。しかし、なぜ?

問題のオブジェクト、ここでは「エントリ」は、ネットワーク経由で送信するためにクエリ文字列にシリアル化する必要があります。そうすることで、オブジェクトの各プロパティを通過します。

まず、(私にとっては7610行目で)オブジェクトかどうかをチェックしますisPlainObject。以前はそうだったかもしれませんが、機能を持っていてもそうはなりません。代わりに、次のことを行います。

jQuery.each( a, function() {
    add( this.name, this.value );
});

少し前にaddを定義したので、次のようになります。

add = function( key, value ) {
    // If value is a function, invoke it and return its value
    value = jQuery.isFunction( value ) ? value() : value;
    s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
};

jQueryが愛情を込めて提供してくれたコメントに注意してください。オブジェクトのすべてのプロパティを調べ、1つが関数の場合は、関数の戻り値を「キー/値」ペアの「値」として使用します。値を取得するためにここを呼び出していました(もちろん、関数が単にアラートを呼び出したためにdoStuff返されます)undefined

私自身のために、ドキュメントはこれを実際には明示していないことを付け加えておきます。私はいつもそれが機能を無視すると思っていましたが、それが間違いなく無視されないのは良いことです。

データオブジェクト、文字列

サーバーに送信されるデータ。まだ文字列でない場合は、クエリ文字列に変換されます。GETリクエストのURLに追加されます。この自動処理を防ぐには、processDataオプションを参照してください。オブジェクトはキー/値のペアである必要があります。値が配列の場合、jQueryは、従来の設定(以下で説明)の値に基づいて、同じキーで複数の値をシリアル化します。

最後に、簡単なテスト(コードを完全に読んでいない)では、JSON.stringify 関数を完全に無視しているようです。

于 2012-08-08T15:31:56.193 に答える