2009-09-23 16:25:30 UTC
Consider trying to xmlize the following:
<pre>
var Container = function(type, region) {
this.type = type;
this.region = region;
this.items = null;
};
var test = new Container('container-type-1', 'east');
test.items = new Array();
test.items[0] = new Container('container-type-embedded', 'center');
test.items[1] = new Container('container-type-empty', 'south');
<b>var testxml = Sarissa.xmlize(test, 'test', ' ');</b>
</pre>
The xmlize (<b>bolded</b>) line will cause a stack overflow exception, seen as "out of stack space"
in IE and "Too Much Recursion" in Mozilla.
This is because xmlize tries to serialize the method: remove() on the array item and this causes a reentry into the recursive method. Methods never resolves to a leaf-node and cause infinite recursion.
Sarissa.xmlize should <b>not</b> xmlize methods but rather only variables. Therefore, we need to check for this condition. We can do this by placing a check (shown in bold) below that an object's member is never an instanceof type Function.
When we run the above code again (using the new xmlize function) we no longer get an error and can recurse much more complex object structures.
<pre>
Sarissa.xmlize = function(anyObject, objectName, indentSpace){
indentSpace = indentSpace?indentSpace:'';
var s = indentSpace + '<' + objectName + '>';
var isLeaf = false;
if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String
|| anyObject instanceof Boolean || anyObject instanceof Date){
s += Sarissa.escape(""+anyObject);
isLeaf = true;
}else{
s += "\n";
var itemKey = '';
var isArrayItem = anyObject instanceof Array;
for(var name in anyObject){
<b>
if (anyObject[name] instanceof Function) {
continue;
}
</b>
s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + " ");
};
s += indentSpace;
};
return s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n");
};
</pre>