tags:

views:

67

answers:

3

I was writing a simple recursive function in JavaScript and encountered some really weird behavior. At first I thought it's bug in a browser, but I tried it in FireFox, Chrome and IE9 and they all behave exactly the same way.

The HTML file below runs a simple JS function on page load. The function is recursive (calling itself exactly once). Essentially the function creates a new Array object and returns it. The weird thing is that after the function calls itself recursively, x and y reference to the same object, which as far as I understand it should not happen. Also if you uncomment the last line before return x, the alert "x == y" alert is not shown.

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>JavaScript weirdness...</title>
<script type="text/javascript" language="javascript">
    function RecursiveF(n) {
        x = [ n ];

        if (n > 0) {
            y = RecursiveF(n - 1);
            if (x == y)
                alert('x == y');
        }

        //if (n == 0) return [ n ];

        return x;
    }
</script>
</head><body onload="javascript:RecursiveF(1);"></body></html>

Any hints to why "x == y" alert appears in this page?

+1  A: 

You need a local variable.

var x = [ n ];
Ignacio Vazquez-Abrams
+6  A: 

x and y are by default global variables shared by all recursive calls of the function. If you want them to be local, declare them with the var keyword.

Jeffrey Hantin
A: 

As the guys before said the problem is, that x and y are not local variables but global. Why is this causing a conflict right now?

What JavaScript does when it executes your function is pulling out x and y to the function that calls you function and declares them there. So now x and y are on the same scope. So at the point where you write:

y = RecursiveF(n - 1)

what will happen in the end is, that

return x;

is executed and so the value of x will be assigned to y resulting in

x == y

There you go. By declaring x and y as local variables via the var statement you can overcome this. This way you get new representations of them with each function call rather then overwriting them.

philgiese