1

我有一个名为 的简单对象Entry,直到最近它才具有一些基本属性。在某些事件期间,我将对这些对象执行 REST 操作,以使用 C# 代码中的 API。直到最近,这还不错。我会使用我的小请求服务将这些对象 POST 或 PUT 到 AJAX 请求的主体中,结果如下:

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

最近我在Entry中添加了一个功能。

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

我添加了该功能,但再次质疑其使用背后的用户故事,因此我切换回浏览器,刷新并运行了更多测试。无需在任何地方调用该函数doStuff,就可以看到它的效果。

doStuff用一个简单的警报替换了 's body,果然,每次我在幕后使用 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 亲切地为我们提供的评论。它遍历对象的每个属性,如果一个是函数,它使用函数的返回值作为“键/值”对的“值”。它在doStuff这里调用以获取一个值(当然返回undefined,因为该函数只是调用了一个警报)

为了我自己,我将补充一点,文档并没有真正明确这一点。我一直认为它忽略了功能,但最好不要说它肯定不会

数据对象,字符串

要发送到服务器的数据。如果还不是字符串,则将其转换为查询字符串。它附加到 GET 请求的 url。请参阅 processData 选项以防止此自动处理。对象必须是键/值对。如果 value 是一个数组,jQuery 会根据传统设置的值(如下所述)序列化具有相同键的多个值。

最后,通过一个简单的测试(不是完整阅读代码),似乎JSON.stringify 确实完全忽略了函数。

于 2012-08-08T15:31:56.193 回答