Это классический случай You must remember this
. Самый простой ответ в вашем случае является локальной переменной в функции инициализации:
var field1 = {
fieldId:"#field1",
field:"",
init:function(){
var self = this; // <=== change here
$.ajax({
type:"GET",
url:'some/url/to/get/values/from',
cache:false,
success: function(data){
alert(self.fieldId); // <=== and here
}
});
}
};
field1.init();
Или попеременно использовать context
аргумент функции ajax
:
var field1 = {
fieldId:"#field1",
field:"",
init:function(){
// <=== change here (no `this.field = this;`)
$.ajax({
type:"GET",
url:'some/url/to/get/values/from',
cache:false,
context: this, // <=== and here
success: function(data){
alert(this.fieldId); // <=== and here
}
});
}
};
field1.init();
В основном, в JavaScript, значение this
во время вызова функции полностью определяется как функция называется, а не там, где она определена как на некоторых других языках (C++, Java, C#, ...). Когда jQuery вызывает обратный вызов success
функции ajax
, он должен установить this
. По умолчанию он устанавливает объект, представляющий параметры вызова ajax, но используя context
, вы можете указать jQuery, чтобы установить его на что-то еще, что позволяет использовать в обратном вызове, чтобы обозначить то же самое, что и this
, когда вы звоните ajax
,
Первое решение использует тот факт, что success
обратного вызова является закрытием над контекстом вызова init
(не волнуйтесь, closures are not complicated), и таким образом, создав переменный (self
) и придав ему значение this
, мы можем надежно ссылаться на объект через self
в пределах замыкания (обратный вызов success
).
Пути, в которых this
установлен в JavaScript:
При вызове функции, получая ссылку на функцию от свойства объекта в рамках одного и того же выражения, что и вызов, this
в пределах вызов функции будет объектом, из которого вы получили свойство. Поэтому, учитывая:
var obj = {
firstName: "Fred",
speak: function(msg) {
alert(this.firstName + " says " + msg);
}
};
затем
obj.speak("hi"); // alerts "Fred says hi", because `this = obj` within the call
Обратите внимание, что он должен быть частью одного и того же выражения, что и вызов. Это делает не работы:
var s = obj.speak; // Getting a reference to `obj`'s `speak`
s("hi"); // alerts "undefined says hi", because `this` is not
// `obj` during the call
Использование call
или apply
. Это функции всех функций JavaScript. Они позволяют вам вызвать функцию и явно указать, что будет this
во время разговора.Так что, учитывая obj
выше:
var s = obj.speak; // Getting a reference to `obj`'s `speak`
s.call(obj, "hi"); // alerts "Fred says hi", we explicitly made `this = obj`
// within the call
Единственное различие между call
и apply
является то, что при использовании call
, если вы хотите, чтобы передать аргументы функции, включить их в качестве дискретных аргументов call
, как описано выше (обратите внимание, мы просто прошел "hi"
в качестве второго аргумента call
и call
передал его в качестве первого аргумента функции). С apply
, а не неограниченное количество дискретных аргументов, второй аргумент - это массив аргументов для перехода к функции.
// Example 1: Passing no arguments, no difference.
// These calls do the same thing.
func.call(obj);
func.apply(obj);
// Example 2: Passing one argument (these calls do the same thing).
func.call(obj, arg);
func.apply(obj, [arg]); // note that it's in an array
// Example 3: Passing two arguments (these calls do the same thing).
func.call(obj, arg1, arg2);
func.apply(obj, [arg1, arg2]); // Again, the args are in an array
Спасибо Су много это было действительно полезно, после того, как возиться с «это» в течение некоторого времени вы теряете надежду, когда вы не знаете, что вы ищете :) –
Что делать, если я добавить сложности при наличии две функции init, а также добавление draw ... init вызывает draw, но тогда мне нужно поддерживать настройку self или this в контексте, есть ли простой способ установить переменную, доступную для всего поля1? –