JS scope of member functions I was writing a program that used a bit of recursion with objects, and it wasn't working at all. After debugging I realized that JS's evil scope was playing nasty tricks.

To spare you guys a wall of text code, I wrote a smaller program:

//Class definition and framework:
TestClass=function(label,level){
    this.label=label;
    this.level=level;

}

TestClass.prototype.recur=function(){
   r=Math.random(); //initialise a local variable
   document.write(this.label+":"+r+"&lt;BR/&gt;");
   if(this.level==0){return;} //exit after this if level==0, we don't want to blow up the call stack
   x=new TestClass("inner1",0)
   x.recur();
   document.write(this.label+":"+r+"&lt;BR/&gt;"); //Check if r has changed
   y=new TestClass("inner2",0)
   y.recur(); 
   document.write(this.label+":"+r+"&lt;BR/&gt;"); //check if r has changed
}

//Run this:
a=new TestClass("outer",1);
a.recur();


Output:

outer:0.5542382076382637
inner1:0.7689833084587008
outer:0.7689833084587008
inner2:0.24465859192423522
outer:0.24465859192423522


As one can see, the value of r in the outer function has changed. From this, I see that JS joins the scope of a function with a function (recursively) called in itself. This seems slightly icky and illogical.

My own solution to this was to make every locally initialized variable a member variable. In this example, I would replace all instances of r with this.r.

Then, since I like my objects to be clean, I wrote a garbage collector. Final code would be somewhat like:

//Class definition and framework:
TestClass=function(label,level){
    this.label=label;
    this.level=level;

}
TestClass.allowedProperties=["label","level"] // do NOT blow these up during garbage collection
TestClass.prototype.recur=function(){
   this.r=Math.random(); //initialise a local variable
   document.write(this.label+":"+this.r+"&lt;BR/&gt;");
   if(this.level==0){return;} //exit after this if level==0, we don't want to blow up the call stack
   x=new TestClass("inner1",0)
   x.recur();
   document.write(this.label+":"+this.r+"&lt;BR/&gt;"); //Check if r has changed
   y=new TestClass("inner2",0)
   y.recur(); 
   document.write(this.label+":"+this.r+"&lt;BR/&gt;"); //check if r has changed
}

//Garbage collector:
TestClass.prototype.cleanup=function(){
    for(x in this){
        if(TestClass.allowedProperties.indexOf(x)==-1){
            delete this[x]; 
        }
    }
}


//Run this:
a=new TestClass("outer",1);
a.recur();
a.cleanup();


This manages the job reasonably well, and cleans up after itself. But I feel that this is a rather inelegant way to do it. Is there a better, elegant way to deal with this form of evil javascript scoping?
"From this, I see that JS joins the scope of a function with a function (recursively) called in itself."

No, it doesn't.  You created a global variable called "r", not a method variable, and so there is only one "r", and it is accessible to all your JavaScript code.

Thou shalt always use var to declare a variable.