PDA

View Full Version : Get the Parent object, (not DOM)



johnnyb
Mar 7th, 2008, 09:55 PM
So, this has been bothering me for a while.

I would like to be able to have an object, with a child object:

var obj.child;

And, from a function that has been passed the childobject, I would like to be able to get a reference to the parent:

function coolness(child) {
// child is the child object from above
// how do I get a reference to obj so that I can do stuff with it?
}


I plan on using this with XHR calls so that I can attach the XHR object to a DOM object, then when a response is received the function (coolness, above), can do stuff to the DOM object. I don't want to have to give the DOM object an ID.

I've searched around, but when you search for "Parent Object" or "Child Object" you get a lot of references to how to get these things in the DOM. I want to get the parent of my XHR object, which, I think, isn't part of the DOM.

Thanks, in advance.

John

liorean
Mar 8th, 2008, 12:22 AM
So, this has been bothering me for a while.

I would like to be able to have an object, with a child object:

var obj.child;That's a syntax error - the var statement does not allow member lookups on the left hand side, only plain identifiers. But anyway, that's not what your question was about.
And, from a function that has been passed the childobject, I would like to be able to get a reference to the parent:

function coolness(child) {
// child is the child object from above
// how do I get a reference to obj so that I can do stuff with it?
}


I plan on using this with XHR calls so that I can attach the XHR object to a DOM object, then when a response is received the function (coolness, above), can do stuff to the DOM object. I don't want to have to give the DOM object an ID.

I've searched around, but when you search for "Parent Object" or "Child Object" you get a lot of references to how to get these things in the DOM. I want to get the parent of my XHR object, which, I think, isn't part of the DOM.The member relationship is one-way, from base object to member object. A member of one object may have an arbitrary number of other parents as well, not just that one object, it's impossible to tell. Some of those base objects may be objects that are not script accessible at all. So it would be impossible to tell - even if we could tell, the scripting engine wouldn't know which base object is the one you're interested in.

Also, if this member relationship was two-way, then the only objects that are not reachable from any other object would be function scoped variables after the functions have exited with no closures remaining or objects that have been explicitly nulled out or deleted, which makes garbage collection useless! (All members of root objects would be keeping the root objects alive, which means that you either need to remove ALL members of a root object or explicitly null out the particular branches in the member tree in order to get the objects marked in dead object detection so that they can be garbage collected.) In other words: a program wouldn't be able to reclaim memory unless the programmer explicitly made sure that particular bit of memory was reclaimed.

The only time the engine actually remembers the base object is when doing method calls. It looks up the base object and sends it as the this-value of the function. It can do this only because use of the member coincides with lookup of the member, so it by necessity knows which base object to use of a possibly very large number of potential base objects.



Three mutually independent suggestions:
Use closures to remember the base object. (private, good idea)
Store the particular base object you're interested of in a property of the member object. (public, potential memory leak in ie, but may still be a not-bad idea)
Store the base object in a public variable or as a member of another object altogether. (public, bad idea, but it works if you're not sending any information around that you don't have reason to want to keep secret, such as user data)

mjlorbet
Mar 8th, 2008, 12:50 AM
i think this is what you're getting at



function xhrThread(threadPool, id){
this.parent = threadPool;
this.id = id;
}
xhrThread.prototype = {
parent: null,
id: "",
notifyParent: function(slf){
slf.parent.notify(this.id);
},
request: function(url, data, method){
var xreq = new XMLHttpRequest();
xreq.open(method?method:"post", url, true);
var Me = this;
xreq.onreadystatechange = function(){Me.notifyParent(Me)};
xreq.send(data?data:"");
}
}
function xhrInfoObject(url, method, data, notification){
this.url = url;
this.method = method;
this.data = data;
this.notification = notification;
this.threadID = url + (new Date());
}
xhrInfoObject.prototype={
url: "",
method: "",
data: "",
notification: null,
threadID: ""
};
function xhrThreadPool(maxThreads){
this.maxThreads = maxThreads?maxThreads:2;
this.threads = new Array();
this.usedThreads = 0;
}
xhrThreadPool.prototype = {
maxThreads: 2,
usedThreads: 0,
threads: new Array(),
queue: new Array(),
promoteQueue: function(){
if(this.usedThreads < this.maxThreads){
var nonNullAt = -1;
for(var a = 0; a < this.queue.length; a++)
if((this.queue[a] != null) && (nonNullAt == -1))
nonNullAt = a;
if(nonNullAt != -1)
{
var nullThreadAt = -1;
for(a = 0; a < this.threads.length; a++)
if((nullThreadAt == -1) && (this.threads[a] == null))
nullThreadAt = a;
if(nullThreadAt == -1)
nullThreadAt = this.threads.length;
this.threads[nullThreadAt] =
{thread: new xhrThread(this, this.queue[nonNullAt].threadID),
info: this.queue[nonNullAt]};
this.queue[nonNullAt] = null;
this.threads[nullThreadAt].thread.request(this.threads[nullThreadAt].info.url, this.threads[nullThreadAt].info.data, this.threads[nullThreadAt].method);
this.usedThreads++;
}
else{
this.queue = new Array();
this.queue.length = 0;
}
}
if(this.usedThreads == 0){
this.queue = new Array();
this.queue.length = 0;
this.threads = new Array();
this.threads.length = 0;
}
},
queueItem: function(url, method, body, notify){
this.queue.push(new xhrInfoObject(url, method, body, notify));
for(var a = 0; a < (this.maxThreads-this.usedThreads); a++)
this.promoteQueue();
},
notify: function(threadID){
for(var a = 0; a < this.threads.length; a++)
if((this.threads[a] != null) && (this.threads[a].info.threadID == threadID)){
if(this.threads[a].info.notification)
this.threads[a].info.notification();
this.threads[a] = null;
this.promoteQueue();
this.usedThreads--;
}
}
}


And there you have it, it sounds like what you're getting at i think, the example allows you to create a threadPool of xhr requests & queue them to be executed as a thread slot frees up, when the thread has finished executing, it calls the thread pool object to clean up and notify the appropriate module to handle the response. OK, with my last edit, i put in the tested version of the script, it works, so hopefully it's what you're looking for.

johnnyb
Mar 8th, 2008, 05:09 AM
Wow - lots of good information - and a great function!

Thanks a lot for the info - I'm going to dissect the function - AND try to learn about closures.

Thanks again.