Как добавить свойства к объекту в IE6?

У меня есть особенно сложная проблема с AJAX, которая отлично работает в IE7 и Firefox, но не в IE6.

У меня очень простая самодельная структура AJAX, которая требует, чтобы я расширил объект XMLHttpRequest (или в случае IE, XMLHttpRequest ActiveXObject), добавив пару свойств. Соответствующий раздел кода выглядит следующим образом:

//the following is the constructor for our ajax request object - which extends the standard object. It is used in the method below it   
function FD_XMLHttpRequest() {     
  var xmlHttpReq = false;
  if (window.XMLHttpRequest) { // Mozilla/Safari
    xmlHttpReq = new XMLHttpRequest();
  } else if (window.ActiveXObject) { // IE
    xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
  }
  //we now have the request object - extend it with things we might need to store with it
  xmlHttpReq.onReturnFunc = null; //******ERROR IN IE6******
  xmlHttpReq.targetDivId = null;  //******ERROR IN IE6******
  return xmlHttpReq;  
} 
//To use:
myXHReq = new FD_XMLHttpRequest();
myXHReq.onReturnFunc = someFunction; 
myXHReq.targetDivId = "myDiv";  

Проблема заключается в том, что FF и IE7 позволяют расширять объект таким образом, но IE6 не делает (он жалуется, что "Object не поддерживает это свойство или метод" ). Я пробовал использовать свойство "prototype" и различные методы "реального" наследования, но я не могу понять, что происходит с IE6

Ответ 1

В IE7 вы получаете "собственный XMLHttpRequest объект JavaScript. Как и со всеми объектами JavaScript, вы можете добавить к ним произвольные свойства без проблем - хотя это не всегда хорошая идея, потому что, если будущий браузер добавит реальный собственный член onReturnFunc, вы тогда путаете его.

В IE6 или IE7, когда параметр "native XMLHttpRequest" отключен, вы возвращаетесь к использованию исходного XMLHttpRequest ActiveX. Тем не менее, объекты ActiveX имеют совершенно иное поведение с объектами JavaScript, и одно из отличий заключается в том, что вы не можете добавлять произвольные свойства.

Как правило, у вас должен быть свой собственный класс-оболочка, который содержит любые дополнительные данные, которые вам нужны, и который содержит ссылку на "настоящий объект XMLHttpRequest".

Ответ 2

Проблема заключается в том, что браузер предоставил XMLHttpRequest, который поддерживает expandos. Однако IE6 не имеет XMLHttpRequest, поэтому ваш код падает до использования ActiveXObject. Объект, предоставленный MSXML, не поддерживает расширение.

Лучшим подходом было бы использование закрытия в любом случае, например: -

function getContentForElem(url, elem, completed)
{
    var xhr = getXhr()
    xhr.open("GET", url, true)
    xhr.onreadystatechange = fnstatechange
    xhr.send()
    return xhr;

    function fnstatechange()
    {
       if (xhr.readyState == 4)
       {
           if (xhr.status == 200)
           {
                elem.innerHTML = xhr.responseText;
           }
           if (completed) completed(xhr)
       }
    }
}

function getXhr()
{
    var xhr;
    if (window.XMLHttpRequest)
        xhr = new XMLHttpRequest();
    else
        xhr = new ActiveXObject("MSXML2.XMLHTTP.3.0");
    return xhr;
}