2013-04-03 4 views
3

JQuery.ajax() принимает аргумент settings. Функции для success или error (например) выполняются в контексте этого объекта.JQuery.ajax() делает копию объекта настроек?

var arr = []; 
var a = { 
    url : '/', 
    arbiteraryProperty: 'yeah!', 
    complete:function() { 
     console.dir(arr[0]); 
    } 
}; 

arr.push(a); 

$.ajax(a); 

запускает команду, а затем выводит атрибуты первого элемента обр (что а) следующим образом:

arbiteraryProperty : "yeah!" 
url : "/" 
complete : function() 

Теперь проблема заключается в том, что this ключевого слова внутри выше complete функция на самом деле не ссылается на объект settings. Это интересно, потому что кажется, что JQuery делает копию объекта settings.

var arr = []; 
var a = { 
    url : '/', 
    arbiteraryProperty: 'yeah!', 
    complete:function() { 
     console.log(this.arbiteraryProperty); 
     //this prints 'yeah!' 
     this.arbiteraryProperty = 'nope!'; 
     console.log(this.arbiteraryProperty); 
     //this prints 'nope!' so the value of the attribute in this is changed 
     console.log(a.arbiteraryProperty); 
     //this prints 'yeah!' ie. the value originally existed in the settings object 
    } 
}; 

arr.push(a); 

$.ajax(a); 

Вопрос в следующем: действительно ли JQuery создает дубликат копии объекта настройки? И если да, как я могу заставить его использовать мой объект?

У меня есть приложение, в котором мне нужно сохранить эти объекты в очереди и ожидать, что они будут обновлены при их запуске. Я предполагаю, что одна из альтернатив - использовать настройки context для $.ajax(). Однако это поведение этой функции (создание копии объекта настроек) не было документировано. Или я пропустил это?

+0

Любой объект внутри этой структуры, вероятно, будет ссылаться (не может быть уверен, это может быть глубокая копия). Если это так, это означает, что вы можете сделать '{context: {variable: 3}, complete: function() {this.context.variable = 2}}'. – Dave

+0

Вы можете просто сделать одно из свойств (например, 'arbiteraryProperty') для вашего объекта в очереди, которая должна быть обновлена, поскольку вы можете видеть, что вы все еще можете получить к ней доступ из скопированного объекта. – Bergi

+0

@Dave Не все ли свойство 'context', чтобы изменить то, что означает' this'? Таким образом, это будет просто 'this.variable', а не' this.context.variable'. –

ответ

5

Да, jQuery создает новый объект опций, когда вы вызываете jQuery.ajax(). Результатом является комбинация объекта настроек, который вы передали, и глобального объекта jQuery.ajaxSettings, так что у вас есть правильные значения по умолчанию и любые настройки, которые вы установили глобально, даже если вы явно не установили их в переданном объекте.

Это можно увидеть в source code для JQuery 1.9 на линии 7745:

// Create the final options object 
s = jQuery.ajaxSetup({}, options), 

Обычно вы используете context свойство, чтобы указать другое значение для this внутри функции обратного вызова, так:

options = { 
    url: '/', 
    ..., 
    context: a 
} 

Однако круговая ссылка в вашем случае (a, ссылающаяся на себя в одном из своих свойств) может вызвать проблемы, если слияние делает глубокую копию.

+0

Я не верю, что это сделало бы глубокую копию, потому что если бы это было так, это сделало бы «контекст» бесполезным в большинстве случаев. – Dave

+0

a) Он делает глубокую копию, но исключает из нее определенные свойства, такие как 'context'. Поиск 'ajaxextend' и' flatoptions' в источнике b) OP не имеет круговой ссылки в своем примере, 'arr' не является свойством' a'. – Bergi

Смежные вопросы