I have an array of lightweight objects, each of which is the Subject of an Observer pattern. To conserve memory, when the Subject is no longer observed, i want to release the object's resources and make it remove itself from the parent array. So how do I ask either the parent object or the Array itself to splice the item, from code within the item itself? What I came up with is something like:
var parentObj = {
items : [],
addItem : function () {
var newItem = new ItemObj;
items.push(newItem);
},
removeItem : function (item) {
for (var i = this.items.length; i--; i < 0) {
if (this.items[i] == item) {
this.items.splice(i, 1);
return;
}
}
}
};
function ItemObj() {}
ItemObj.prototype = {
observers : [],
observerRemove : function(observer){
//find observer in observers array and splice it out
....
//now here's the part where it gets tricky
if (this.observers.length == 0) {
parentObj.removeItem(this);
}
},
//observerAdd.... etc
};
Which works, but only because parentObj is a named variable, if it were a class, it would not be so easy. Also, this seems a little clumsy. It would be nice if ItemObj could have some reference to it's parent Array object, but I can't find that. Any suggestions? Perhaps passing a reference from parentObj of itself to each ItemObj? as in
newItem.parentArray = this.items;
when creating the itemObj? Again, seems clumsy.
Why not just add a reference to the parent in the item class.
var parentObj = {
items : [],
addItem : function () {
var newItem = new ItemObj;
newItem.parent = this; // set the parent here
items.push(newItem);
},
removeItem : function (item) {
for (var i = this.items.length; i--; i < 0) {
if (this.items[i] == item) {
this.items.splice(i, 1);
return;
}
}
}
};
function ItemObj() {}
ItemObj.prototype = {
parent: null,
observers : [],
observerRemove : function(observer){
//find observer in observers array and splice it out
....
//now here's the part where it gets tricky
if (this.observers.length == 0) {
this.parent.removeItem(this); // use the parent here
}
},
//observerAdd.... etc
};