Класс JavaScript вызывая XMLHTTPREQUEST Внутреннее, затем обработка OnReadyStateChange
-
26-09-2019 - |
Вопрос
Эта вещь почти работает:
function myClass(url) {
this.source = url;
this.rq = null;
this.someOtherProperty = "hello";
// open connection to the ajax server
this.start = function() {
if (window.XMLHttpRequest) {
this.rq = new XMLHttpRequest();
if (this.rq.overrideMimeType)
this.rq.overrideMimeType("text/xml");
} else
this.rq = new ActiveXObject("Microsoft.XMLHTTP");
try {
this.rq.onreadystatechange = connectionEvent;
this.rq.open("GET", this.source, true);
this.rq.send(null);
this.state = 1;
} catch (err) {
// some error handler here
}
}
function connectionEvent() {
alert("i'm here");
alert("this doesnt work: " + this.someOtherProperty);
}
} // мои занятия
Таким образом, это не более чем наличие объекта XMLHTTPREQUEST в качестве члена моего класса, а не в глобальном масштабе определенного и называть его традиционным способом. Однако внутри моей функции обратного вызова Shickevent означает значение «этого» теряется, даже если сама функция имеет место внутри MyClass. Я также позаботился о том, чтобы объект, который я создал от MyClass, поддерживается достаточно длинным (объявлен глобальным в сценарии).
Во всех примерах использования JavaScript классов, которые я видел, «Это» все еще доступен внутри внутренних функций. Для меня это не так, даже если я возьму свою функцию снаружи и сделаю это myclass.prototype.ConnectionEvent. Что я делаю неправильно? Спасибо.
Решение
Причина, по которой она не работает, это то, что в JavaScript, this
определяется полностью, как функция называется, не там, где он определяется. Это отличается от некоторых других языков.
Иметь this
Значит то, что вы ожидаете, вам придется убедиться, что явно «привязка» это:
this.start = function() {
var self = this; // Set up something that survives into the closure
/* ...lots of stuff omitted... */
this.rq.onreadystatechange = function() {
// Call `connectionEvent`, setting `self` as `this` within the call
connnectionEvent.call(self);
};
Есть больше информации о this
управление внутри этот блог пост, но в принципе: когда функция вызывается без каких-либо особых усилий, сделанных для установки this
, this
Внутри функции всегда будет глобальный объект (window
, на браузерах). Есть два способа установить this
При звонке:
- С использованием
Function#call
(илиFunction#apply
) Как я сделал выше, проходя в ссылке на объект, чтобы использовать какthis
как первый параметр. Который вызывает функцию и наборыthis
к тому, что вы проходили. Разница между#call
а также#apply
Это то, как вы поставляете дополнительные аргументы, чтобы пройти в функцию. С участием#call
вы поставляете их как дальнейшие аргументы#call
Вызов (например,func.call(thisArg, arg0, arg1, arg2)
), тогда как с#apply
Вы поставляете их как массив во втором аргументе (func.apply(thisArg, [arg0, arg1, arg2])
). - Используя пунктирную запись: если у вас есть объект, который имеет свойство с назначенной им функцией (например, ваша
start
Свойство), вызывая его с помощью экземпляра объекта, точка и имени свойства (this.start()
илиfoo.start()
, и т. Д.) Позвонит функцию и установитьthis
к экземпляру объекта в пределах вызова. Так что пунктирное обозначение делает два полностью различно Вещи: смотрит на свойство и находит функцию в качестве значения и вызывает функцию такой, чтоthis
установлен на объект во время вызова. Буквально это как:var f = obj.func; f.call(obj)
.
Слегка без темы, но: запретить действительно вескую причину, я бы не изобрел это колесо. Там есть много библиотек, чтобы просто призывы XHR. jquery, Прототип, Закрытие, и почти все остальные.