In the first example, you do not need additional closure. This works fine:
function request(url, callback){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ callback(xhr); }; xhr.open('GET', url, true); xhr.send(''); }
In modern browsers (or browsers with polyfill fixes ) you can also do this:
function request(url, callback){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = callback.bind(null, xhr); xhr.open('GET', url, true); xhr.send(''); }
edit - also pay attention to @ Rainos answer. You do not need to pass an XHR object as a parameter.
change again - in response to a legitimate comment, you asked why your original idea would not work:
function request(url, callback){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = callback(xhr); xhr.open('GET', url, true); xhr.send(''); }
The problem with this line is here:
xhr.onreadystatechange = callback(xhr);
This sets the onreadystatechange value returned from the callback function call, then and there. In other words, instead of setting something to be called upon when the state changes, the call is made immediately. This error is really common, because it is easy to read incorrectly. However, at any time, JavaScript sees a link to a function, followed by a list of arguments in brackets, which is interpreted as a request to execute a function call, and not a request to wrap functions around a future function call.
Pointy
source share