javascript singleton scope problems with "this"
Hi i am beginning using the singleton javascript design pattern, but i have some scope problems. Here i am just experimenting with a small ajax, retrieve and store singleton. From within a function in the singleton i call another function (this.ready, called when the ajax has retrieved and stored the data) but it seems "this" doesn't refer to the singleton, rather it refers to "Object #XMLHttpRequest" according to chrome debugger, firefox just says it's undefined.
var mag = {
magObj: [], // object to store the retrieved json data
getData: function(){
request = getHTTPObject(), // defined externally
request.onreadystatechange = this.setData;
request.open("POST", "be.php", true);
request.send(null);
},
setData: function(){
if (request.readyState == 4)
{
this.magObj = JSON.parse(request.responseText);
this.ready(); // this line yields the error, seems "this" does not refer to the singleton
}
else if (request.readyState == 1)
{
}
},
ready: function() {
console.log('ready');
},
construct: function(){
this.getData();
},
}
Also if i try to declare the getHTTPObject() as a singleton variable in the top, instead of using global variable i get the error Cannot read property 'readyState' of undefined. Again it's "this" getHTTPObject that seems to be undefined even though i set it at the top:
var mag = {
magObj: [],
request: getHTTPObject(),
getData: function(){
开发者_JS百科 this.request.onreadystatechange = this.setData;
this.request.open("POST", "be.php", true);
this.request.send(null);
},
setData: function(){
if (this.request.readyState == 4) // debugger says this.request is undefined
{
this.magObj = JSON.parse(this.request.responseText);
}
else if (this.request.readyState == 1)
{
}
},
construct: function(){
this.getData();
},
}
If it is a singleton you could try
var mag = {
magObj: [], // object to store the retrieved json data
getData: function(){
request = getHTTPObject(), // defined externally
request.onreadystatechange = this.setData;
request.open("POST", "be.php", true);
request.send(null);
},
setData: function(){
if (request.readyState == 4)
{
this.magObj = JSON.parse(request.responseText);
mag.ready(); // this line yields the error, seems "this" does not refer to the singleton
}
else if (request.readyState == 1)
{
}
},
ready: function() {
console.log('ready');
},
construct: function(){
this.getData();
},
}
#1
setData
is a callback function for the XMLHttpRequest
object. It's therefore run in the scope of the XMLHttpRequest
object. Use mag
instead of this
.
#2
Same as #1
: this
refers to the XMLHttpRequest
, rather than you mag
variable.
To solve the scope problem, you need to use the concepts of closures in javascript. basically a scope where functions have access to properties and methods in the context that created that function.. ok for a more clear explanation.. try initializing your mag object as a function..
var mag = function(){
var magObj = [];
var getData = function(){
//here you'll have access to the magObj collection
};
}
The previous is a classic example of a javascript closure.. Of course you instantiate the mag object simply as a function invocation mag();
Hope this helps.
精彩评论