Класс JavaScript вызывая XMLHTTPREQUEST Внутреннее, затем обработка OnReadyStateChange

StackOverflow https://stackoverflow.com/questions/2836469

Вопрос

Эта вещь почти работает:

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 При звонке:

  1. С использованием Function#call (или Function#apply) Как я сделал выше, проходя в ссылке на объект, чтобы использовать как this как первый параметр. Который вызывает функцию и наборы this к тому, что вы проходили. Разница между #call а также #apply Это то, как вы поставляете дополнительные аргументы, чтобы пройти в функцию. С участием #call вы поставляете их как дальнейшие аргументы #call Вызов (например, func.call(thisArg, arg0, arg1, arg2)), тогда как с #apply Вы поставляете их как массив во втором аргументе (func.apply(thisArg, [arg0, arg1, arg2])).
  2. Используя пунктирную запись: если у вас есть объект, который имеет свойство с назначенной им функцией (например, ваша start Свойство), вызывая его с помощью экземпляра объекта, точка и имени свойства (this.start() или foo.start(), и т. Д.) Позвонит функцию и установить this к экземпляру объекта в пределах вызова. Так что пунктирное обозначение делает два полностью различно Вещи: смотрит на свойство и находит функцию в качестве значения и вызывает функцию такой, что this установлен на объект во время вызова. Буквально это как: var f = obj.func; f.call(obj).

Слегка без темы, но: запретить действительно вескую причину, я бы не изобрел это колесо. Там есть много библиотек, чтобы просто призывы XHR. jquery, Прототип, Закрытие, и почти все остальные.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top