views:

321

answers:

3

My application has something like the following structure

window.object1;
window.object2;
$(document).ready(function() {
   window.object1 = new type1object();
});

function type1object() {
   //lots of code
   this.property = 'property';
   window.object2 = new type2object();
}

function type2object() {
   //lots of code
   this.property = new type3object();
}

function type3object() {
   //lots of code
   console.log(window.object1);
   this.property = window.object1.property;
}

The problem is that whenever I try to access window.object1 from anywhere other than the document ready callback it comes back as undefined, this is even though when I inspect the DOM window.object1 is defined exactly as I expect it to be.

I've tried doing the same as above but using simple global variables instead (i.e. var object1 instead of window.object1) ... Tried declaring initial dummy values for object1 and object2 in various places... but run up against the same problem.

Does anyone know why I can't access my global variables globally?

+1  A: 

Since you are not setting the value of window.object1 until you are inside the document ready function, you wont be able to access it until it has run.

Nothing in your code shows that you couldn't just remove that document ready call altogether. It is generally reserved for waiting for elements to load in the dom, which it doesn't seem like you are doing. If you somehow do have elements that need to be waited on inside of code that isn't there, just put your script at the bottom of the page, right above the tag. This will do the equivalent of document ready.

Alex Sexton
but even if I put a console.log(window.object1) after document ready it shows undefined
wheresrhys
That's exactly my point. The code inside of the document ready call is not executed right away. So code that you put after it will likely run before it does.
Alex Sexton
ok... but even so the console.log within type2object occurs within the document ready as window.object2 is created within the document ready.
wheresrhys
You are instantiating new instances of the function, not executing the function. So it doesn't really occur there.
Alex Sexton
+2  A: 

You have to make sure you are evaluating window.object1 after initiating it. That is, in your case, only after document.ready finished executing

If you look at this example below you can see that at click both are initialized.

<html>
    <body>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"&gt;&lt;/script&gt;
    <script>        
        $(document).ready(function() {
           window.object1 = new type1object();
           window.object2 = new type2object();
           //console.log(window.object1);
        });

        $(document).click(function(){
            console.log(window.object1);
            console.log(window.object2);            
        });

        function type1object() {
        }

        function type2object() {
        }

    </script>
Tzury Bar Yochay
Interesting. So now the question is, why would the type2object run before the type1object has finished constructing itself? I always thought javascript was a one task at a time language (as long as not using ajax).
wheresrhys
+1  A: 

writing the code really stripped out made the answer fall out - I was creating something that referenced object1 during the construction of object1.

So I changed it to this, so that the object exists (though with no content) before anything tries to reference it:

window.object1;
window.object2;
$(document).ready(function() {
   window.object1 = new type1object();
   window.object1.construct();
});

function type1object() {
   //lots of code
   this.construct = function() {
      this.property = 'property';
      window.object2 = new type2object();
   };
}

function type2object() {
   //lots of code
   this.property = new type3object();
}

function type3object() {
   //lots of code
   console.log(window.object1);
   this.property = window.object1.property;
}
wheresrhys
Might be better to pass references to the constructor for parent/related object... note: this can cause a memory leak within your page as objects are created/destroyed, not a huge issue as it's limited to the one page, but in a large application open for an entire day or more, this can become an issue. Especially in older browsers.
Tracker1