2

I am learning javascript and jquery and wondered whether it is good or bad practice to nest all my functions within $(document).ready(function). Is there any difference between this:

function someFunction()
{
  return someThing;
}

$(document).ready(function()
{
  // some code
  ...
  someFunction();
});

and this:

$(document).ready(function()
{
  // some code
  ...
  function someFunction()
  {
    return someThing;
  }

  someFunction();
});

Be gentle - I'm pretty new to this!

Rob
  • 76,700
  • 56
  • 158
  • 197
  • 3
    If you want to use someFunction outside document.ready then do the first. Otherwise the second. – Raynos Mar 29 '11 at 18:49
  • Encapsulating all of your code inside of a self-invoking function will eliminate it from the global scope without having to cram all of your code into the `ready` handler. The syntax for such is: `(function (){ //code }());`. –  Mar 29 '11 at 19:12
  • He would then not be able to call his functions form the `on ready` handler (unless he declared them as properties of the window object - defeating the point of the self-invoking anonymous function). – typeof Mar 29 '11 at 19:31
  • I think it's bad practice to put all the stuff in one place, be it `$(document).ready()` or anything else. I would try a separation of concerns. If you're interested how this can be accomplished with jQuery, [read here](http://larselrund.com/2011/08/03/mvp-with-javascript/). – Neovibrant Aug 04 '11 at 16:38

5 Answers5

3

You forgot at least one :-)

function someFunction()
{
  return someThing;
}

$(someFunction);

Generally there is no difference between: $(document).ready(argFunc) and $(argFunc). The other variations you listed have all different scopes for different things.

For example, in your 2nd block you declare someFunction inside a non-global scope, while your first and my example declare it in the global scope, which has implications for reachability.

Also, technically, with both of your variations you produce one extraneous function call. Because in this case, all you call is one function (which you can also write like my example).

UPDATE1: To add some additional info and to further the discussion about scopes - JavaScript has very loose requirements for existence of variables. If it doesn't find them in the current scope, it wall just traverse the call chain upwards and look for it - until it finds it or not. That is why you can access the jQuery object ($) from anywhere.

There is however this:

someFunction($) {
  // You can use $ here like always 
  return someThing; 
} 
$(someFunction);

This means, that the handlers (there can be more than one) for the document ready event of jQuery get passed jQuery itself as an argument.

If you specify this parameter for your function, you'll use that one, if you reference it. Otherwise, you are using the global one. That reduces the length of the upward look-up - chain. That is completely irrelevant from a performance stand point.

But, by specifying this as a parameter, you make it absolutely clear where the jQuery object is coming from. Even that might be irrelevant.

I just wanted to show, that these callback-type functions in jQuery often take parameters that are useful. So if you are ever stuck and need access to some object you don't have, it might be worthwhile to check the jQuery docs to see, if there is not a parameter, that does what you want.

To conclude this update, I very much like the first comment to the question, which is a much better answer than mine.

UPDATE2: On the point of multiple callbacks for document ready (or any event binder in jQuery for that matter): You can do this:

$(func1); // or $(document).ready(func1);
$(func2); // or $(document).ready(func2);

Both will get called as soon as jQuery fires its document ready event. That might come in handy depending on the perspective. Some would say, it encourages spreading your logic around. Others might say, it allows for cleaner separation of all the things that need to be done on document ready.

skarmats
  • 1,907
  • 15
  • 18
  • I didn't know about that shortcut for `$(document).ready`! Thanks for posting that. – Andrew Anderson Mar 29 '11 at 19:04
  • To go further, the most precise signatures are: function someFunction($) { // You can use $ here like always return someThing; } $(someFunction); That means, that a document ready callback receives jQuery as a parameter - thus helping to reduce the lookup chain in nested scopes. By that way, you are in actuality not using the global jQuery object but the one in the scope of your method. EDIT: Maybe, I should put that into the post. Looks kind of illegible. – skarmats Mar 29 '11 at 19:08
  • @skarmats: please elaborate with a post! – Rob Mar 29 '11 at 19:19
  • Btw, for my examples, the return statement in someFunction will not accomplish much. But this is different for other event handlers in jQuery. returning false often stops event bubbling and so forth. You can find information about that in the jQuery docs – skarmats Mar 29 '11 at 19:34
  • I love UPDATE2 - that's really useful to know. – Rob Mar 29 '11 at 19:44
2

yes. The first way puts someFunction in the global scope so that it can be called by anyone. If you intend this function to be "private" and only callable by some code then the 2nd way is preferred. Generally you should prefer the 2nd way unless you need to export the function into global scope.

Brandon
  • 38,310
  • 8
  • 82
  • 87
2

The differences are subtle, but worth bringing up.

Declared functions outside of DOM ready:

If you don't call the functions until DOM ready, then this is more efficient since it is registering the functions before waiting for the DOM to load (Edit: As is noted in the comments, there will be a slight performance penalty in accessing global variables due to scope resolution). This is very minor and probably not noticeable.

More importantly, you functions become globals, and you can clutter the global scope if you're not namespacing properly:

var myFuncs = {
    someFunction : function() { ... },
    someOtherFunciton : function() { ... }
}; 

Declared inside DOM ready:

Functions are no longer globals, but your functions are registered along with your other DOM ready code.

I would say it's fine to go either way in most cases, but definitely declare your functions under one namespace.

typeof
  • 5,812
  • 2
  • 15
  • 19
  • interesting efficiency argument. On the flip-side, accessing objects/functions in global scope has a slight performance penalty vs accessing locally defined objects/functions because the js engine must walk through the scopes to find it, and when it reaches global scope, it must look it up via string lookup in the *window* map. This probably offsets some portion of the efficiency gains you described. – Brandon Mar 29 '11 at 19:04
  • Good point. I guess you could create a local reference to the global object, circumventing the out-of-scope variable resolution. I'd only do that if I was referencing the global variable frequently. – typeof Mar 29 '11 at 19:21
  • yeah. I think we are both being pedantic here :) – Brandon Mar 29 '11 at 19:24
1

First off, functions are typically only declared if they are going to be used more than once. If you put a function inside the $(document).ready(function) then it won't be available outside the scope of the $(document).ready(function). Check out an article on Javascript Scope.

This is because $(document).ready accepts a function as a parameter and in your two examples you are declaring an inline function (that's the function () {} code in there). Check out a discussion of inline functions vs parameterized functions.

So, it boils down to deciding if you are going to use someFunction() more than once. If so, put it outside the $(document).ready function. Otherwise, you don't really need a function since you are just calling it once.

Community
  • 1
  • 1
Andrew Anderson
  • 441
  • 4
  • 14
  • 1
    But, you can use it more than once from within the DOM ready function. I certainly follow the logic of "if you use it more than once, make a function", but not "make a global function". It'd be better to say "if you use it in multiple scopes, make it a global function", but even then, it's not necessary. – typeof Mar 29 '11 at 19:06
0

As long as someFunction() does not try to manipulate the dom, there is no difference. $(document).ready is called after all elements in the dom have loaded and can be accessed with javascript. If you try to manipulate an item in that page with javascript before it loads, it wont be there and the code will break.

Craig
  • 7,471
  • 4
  • 29
  • 46
  • 4
    This is totally wrong. someFunction() can refer to DOM in either case...as long as it is only **called** after the DOM is ready. Both examples will work equally well. The difference between the two ways is in how the affect the global scope. – Brandon Mar 29 '11 at 18:53
  • @Brandon: You are right. I was thinking about it being called before the dom loads. – Craig Mar 29 '11 at 18:59