This post originated from an RSS feed registered with Python Buzz
by Carlos de la Guardia.
Original Post: Beware of javascript's global scope
Feed Title: I blog therefore I am
Feed URL: http://blog.delaguardia.com.mx/feed.atom
Feed Description: A space to put my thoughts into writing.
When trying to port some code from Python to Javascript I started to get unexpected results from a simple recursive function.
Here is the Python code:
def childrenMarkup(children):
markup=''
for child in children:
markup ='<div dojoType="TreeNode"
widgetId="'+child.id+'"
title="'+child.title+'">'+
childrenMarkup(child.children)+'</div>'
return markup
My first javascript attempt looked like this:
function childrenMarkup(children) {
markup='';
if (children.length==0) { return markup; }
for (var i=0;i<children.length;i ++ ) {
var child=children[i];
markup ='<div dojoType="TreeNode" widgetId="'+
child.widgetId+'" title="'+child.title+'" object="'+
child.object+'">'+childrenMarkup(child.children)+'</div>';
}
return markup
}
This caused the script to return strange values that did not reflect the tree structure I wanted to convert to HTML.
Python is very similar in many respects to Javascript, so I thought a semi-direct translation would work. Of course, you may already know that I forgot a key Javascript scoping rule, which is almost exactly the opposite from Python's: all variables are global unless declared with the var keyword.
That means my children array and for loop variable got squashed with each call, and the way it happened depended on the composition of the tree, hence the unconsistent results.
Halfway through my suffering I remembered reading this somewhere before, so after correcting my work I looked for it. Sure enough , I found it right away on Mozilla's Javascript reference. My final version took this into account:
function childrenMarkup(children) {
var branches=children;
var markup="";
if (branches.length==0) { return markup; }
for (var i=0;i<branches.length;i ) {
var child=branches[i];
markup ='<div dojoType="TreeNode" widgetId="'+
child.widgetId+'" title="'+child.title+'" object="'+
child.object+'">'+childrenMarkup(child.children)+'</div>';
}
return markup
}