2013-04-05 118 views
2
(function (send) { 

    XMLHttpRequest.prototype.send = function() { 

     console.log(this.onreadystatechange); //null 
     send.apply(this, arguments); 
    }; 

})(XMLHttpRequest.prototype.send); 

爲什麼this.onreadystatechange爲空?根據this它應該存在並且類型爲functionXMLHttpRequest對象上缺少onreadystatechange()

+0

,它的'null'而不是'undefined'(或拋出一個不確定的除外),這一事實應該解釋 - 它只是還沒有確定呢。 – Ian 2013-04-05 13:51:34

+0

該函數只是用一些日誌記錄封裝'send'方法。由於您沒有向我們展示使用它的代碼,因此我們無法說出爲何在調用send時函數爲null。 – Quentin 2013-04-05 13:54:14

回答

9

onreadystatechange確實存在 ...這就是爲什麼它是null。如果它不存在,那將是undefined。這一切都取決於它是否已經設置。這顯然已經是一個財產,因爲它是null ...如果它不是,那將是undefined ...或至少"onreadystatechange" in this將是false

下面是一個例子:

var a = new XMLHttpRequest(); 
a.onreadystatechange = function() { 
}; 
a.send(); 

您的控制檯將記錄一個function

如果您有:

var b = new XMLHttpRequest(); 
b.send(); 

您的控制檯將日誌null

這裏有這種情況發生的演示http://jsfiddle.net/3XKx7/

(我清楚地離開了其他步驟出了Ajax請求,這只是爲了說明)

我不是想暗示有一個nullundefined之間的關係 - 我只是說在創建新的XMLHttpRequest時,onreadystatechange將在內部設置爲null。無論您是否將其設置爲功能,都取決於您。

UPDATE

創建/發送XHR方式,一般是這樣的順序:

var xhr = new XMLHttpRequest(); 
xhr.onreadystatechange = function() { // This and `open` could be flip-flopped 
    // whatever 
}; 
xhr.open("POST", url, true); 
xhr.send("data=data"); 

我總是告訴/顯示創建新XMLHttpRequest,那麼無論設置onreadystatechange的順序並打電話open,但只有在這兩個應該我打電話send

所以,如果總是做,onreadystatechange(如果實際設置)不會null並且將是一個function

既然你提到你使用jQuery,我決定重寫send方法像你想,並使一個jQuery $.ajax通話測試(不手動發送XMLHttpRequest)。下面是我的測試 - http://jsfiddle.net/3XKx7/1/

它沒有意義,爲什麼onreadystatechangenull,因爲jQuery 是結合該事件,以請求和完成時的狀態就知道了。所以我決定看看jQuery源代碼。而我發現的是,他們稱之爲事物的順序是:

xhr.open() 
xhr.send() 
xhr.onreadystatechange = function() { 

}; 

這意味着,當你重寫send方法,onreadystatechangenull因爲jQuery的不調用send之前設置它。我不知道他們的理由......可能是爲了防止像你正在做的事情......但我從來沒有聽說過或看到這個慣例被使用。

所以你得到它的值作爲null的原因是因爲jQuery調用send後設置onreadystatechange。這意味着當您覆蓋send並嘗試訪問onreadystatechange屬性時,它尚未設置。

希望這是一個例子,可以幫助您瞭解:http://jsfiddle.net/dMP6q/16/

+0

我想攔截jQuery的Ajax調用使用此。無法弄清楚它爲什麼會爲null(因爲jQuery顯然正在使用它) – Johan 2013-04-05 20:20:03

+0

@Johan Woah,我想我明白你在說什麼了。是的,它爲什麼會被設置爲null是沒有意義的。以下是我用http://jsfiddle.net/3XKx7/1/測試的內容 – Ian 2013-04-05 20:59:39

+0

我應該在問題中更加清楚:/我不知道如何解決它。 – Johan 2013-04-05 21:09:08

1

你應該自己設置它,當狀態改變時這個函數會被調用。這就像其他的事件處理程序,如document.onloadyourelement.onclick

古典你做

var httpRequest = new XMLHttpRequest(); 
    httpRequest.onreadystatechange = function() { 
     if (httpRequest.readyState === 4) { 
       if (httpRequest.status === 200) { 
        // use httpRequest.responseText 
       } 
     } 
    }; 
    httpRequest.open('GET', url); 
    httpRequest.send(); 
+0

隨機問題 - 你知道爲什麼每個人(是的,包括我)總是在**回調中使用'httpRequest' **嗎?爲什麼沒有人使用'this'?這不重要,但我只是想知道。我認爲我從未見過人們使用'this',但是我會爲普通的事件處理程序看到它。 – Ian 2013-04-05 22:29:54

+0

我有時使用這個,但我發現使用你聲明的變量是正常的:你知道它是什麼,而你必須知道使用這個特定回調的上下文是什麼。對於圖像的加載,這也是一樣的。 – 2013-04-06 06:21:17

+0

的確如此。我想我只是想設置一個函數的引用(而不是一個匿名函數),如'xhr.onreadystatechange = stateChange;',你不能在函數中使用'xhr' ...你必須使用'this'。所以對我來說,它總是使用'this',因爲它應該總是引用特定的請求。無論如何,我想這不是太重要,我只是想聽聽你的意見。謝謝:) – Ian 2013-04-06 17:45:53