views:

64

answers:

3

Hi,

I'm working on a proprietary site, and I'm having some issues. I'm using jQuery along with prototype, and I've got it namespaced properly, so in this question assume you can use $ or jQ as a namespaced reference to jQuery.

So I've got a bunch of functions, some mix jQuery and javascript, some plain javascript, some jQuery only. Now, currently some functions are defined within the document.ready jQuery function, and some are defined outside of it, kind of like this:

jQ(document.ready(function($) {

  if ( ifConfig ) {
    //page check, function calls here
    fnc1();
    fnc2();
    fnc3();
    fnc4();
  }

  function fnc1() {
    //fnc code in here
  }
  function fnc2() {
    //fnc code in here
  }
});  //end document.ready

function fnc3() {
}
function fnc4() {
}

Now this is all pseudo code, you can assume the functions are valid and have valid code in them. Recently I was doing some debugging, and one of my functions that was declared and called inside the document.ready said it was undefined. I moved it outside of the document.ready, and everything worked again.

I'm basically trying to understand the order of how functions are initiated/called better, so my question is when do you declare functions inside the document.ready and when do you declare them outside? Do you only declare inside when they're called within that document.ready only? Or should I always just declare them outside of that document.ready?

Thanks.

A: 

(document).ready is more used for things that need to be executed at page load, and not function declarations. If you declare them inside of (document).ready, their scope will be local to that block - if they're only used locally, that's fine and they should be declared there. Otherwise, declare them outside.

So in your example, if the functions are only used in that block, they should be declared in there. If they're used other places additionally, they should be declared outside.

Alex Zylman
So you're saying only declare locally when you have a LOT of local functions used in document.ready. Otherwise just declare globally.
bryan.taylor
Declare locally if they're only used locally. Otherwise declare globally. Sorry if I wasn't clear enough.
Alex Zylman
A: 

If a function is only used inside the document ready function, then declare it inside so you don't pollute the global scope. Otherwise, declare it outside so it the rest of your script has access to those functions.

CD Sanchez
What about with respect to handlers? When you're assigning an event handler inside of document.ready to a function inside document.ready, do you need to declare that in the global scope or only in the local?
bryan.taylor
@bryan taylor: Inside the ready is fine -- since the event handler is being stored in that element's click handler list the reference isn't lost when you exit that scope.
CD Sanchez
+3  A: 

Generally, you should declare & define your own namespace, where all of your application logic (including functions/methods) is located. That way you avoid collision with other scripts on your site + that way your code is much cleaner and easier to maintenaine.

var myapp = function(){
    var foobar1 = null,
        foobar2 = null,
        foobar3 = null;

    return {
        getFoobar1:  function(){
           return foobar1;
        },
        getFoobar2:  function(){
           return foobar2;
        },
        setFoobar1:  function(foo){
           foobar1 = foo;
        },
        clickhandler: function(e){
           alert('I am an event handler, and I am not anonymous');
        }
        // etc.
    };
};

$(document).ready(function(){
    var Application = myapp();

    Application.getFoobar2();

    $(document).bind('click', Application.clickhandler);
});

That pattern (some call it the "method pattern") creates a closured function/object which also guarantees private member variables within your namespace, only accessible through the getter functions from the outside.

This is really only a pretty basic example, you can push this idea & pattern to an extend, which is very nice & a good thing (IMO).

A great book about this stuff which was named and recommended pretty often is "Javascript: The Good Parts" by Douglas Crockford.

jAndy
collusion? Is that right, or did you mean collision?
CD Sanchez
@Daniel: Yay, thanks for the hint.
jAndy
@jAndy: I like this a lot, it's very interesting. How is performance affected by declaring/calling functions using this method?
bryan.taylor
@bryan.taylor: performance is just as good as calling those functions from the global (window) namespace. It's probably slightly slower since we are doing an object lookup and extending the scope chain, but that difference is like nothing and really should stop no one from doing this or similiar.
jAndy