67

Functions come up as undefined if I place them in the document.ready() function:

$(document).ready(function(){
  function foo()
  {
    alert('Bar');
  }
});

foo(); // Undefined

Why does this happen? I'm sure I'm just in need of some simple understanding :)

Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
James Skidmore
  • 49,340
  • 32
  • 108
  • 136

6 Answers6

78

Not sure why defining the function with in the scope of ready() is important to you, but you can make it work by declaring foo up front:

<html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script>
var foo;                           // Here's the difference
$(document).ready(function(){
  foo = function ()
  {
    alert('Bar');
  }
});
</script></head><body>
<input type="button" onclick="foo()" value="Click me">
</body></html>

Obviously you can't call foo() from the inline script immediately after ready() because the ready() code hasn't yet run, but you can call the function later on.

Just make sure that nothing can try to call foo() before the ready() code has run (or make the initial declaration of foo() a harmless function).

RichieHindle
  • 272,464
  • 47
  • 358
  • 399
  • 1
    What if you need to call `foo()` with some parameters? How would you pass them, and how would they be received? – alonso.torres Feb 22 '12 at 23:41
  • 1
    @alonso.torres: Just like any other JavaScript function: `foo = function(x, y, z) {...}` ... `onclick="foo(1, 2, 3)"` – RichieHindle Feb 23 '12 at 17:24
  • @RichieHindle note that "the way you declare the function" matters, see http://stackoverflow.com/questions/11819425/jquery-document-ready-and-function-scope – Adriano Aug 12 '14 at 12:41
  • 1
    @RichieHindle also, if you do NOT add `var foo` and leave the function declaration as you posted `foo = function (){}`, the variable `foo` will have the global scope assign to it. You can simply check this by doing `console.log(window.foo);` after the function was loaded. – Adriano Aug 12 '14 at 12:44
  • 1
    @RichieHindle thanks for your solution, its working ;) – Tahir Afridi Jul 03 '19 at 06:11
27

You can but they must be called within the scope of the ready() method otherwise they lose scope when the ready() method exits.

For example, the code below will work:

$(document).ready(function(){
  function foo()
  {
    alert('Bar');
  }

  foo(); // still in the scope of the ready method
});
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • 1
    Is there any way to get around this? Change the scope? – James Skidmore Jun 28 '09 at 21:06
  • 9
    Simple. Define them outside of the .ready(...) scope. I don't see why you're so attached to doing that. What benefit could it possibly offer you? – Oli Jun 28 '09 at 21:10
  • @Oli, it would have been better from a code organization standpoint to be able to declare it within the .ready() scope. – James Skidmore Jun 28 '09 at 21:18
  • 1
    @James, it would NOT be better from a code standpoint, think of your foo() function as a library or API if it needs to be called from inside and outside the ready scope. In which case, you make it take all necessary arguments and spit out a result, no side effects. – Soviut Jun 28 '09 at 22:09
8

They will come up as undefined if you put them in any scope that is not theirs. If you really want to use them outside of the scope of $(document).ready(...) then you need to declare them externally. Such as:

var foo;

$(document).ready(function(){
  foo = function()
  {
    alert('Bar');
  }
});

foo(); // works now because it is in scope

Hope this helps.

Nick Berardi
  • 54,393
  • 15
  • 113
  • 135
  • @jj_ Hari Om''s solution works because the call to myfnc is within the same scope that myfnc is declared in. – Nishan Dec 02 '15 at 08:31
  • yes `myfnc()` call is, but what about `myfnc(param1, param2)` in the input onclick event? – Redoman Dec 03 '15 at 05:26
  • 1
    Because myfnc is not actually the name of the function. Hari Om creates an anonymous function and assigns it to the variable myfnc. Since the variable myfnc is global (variables in JScript have a global scope unless declared with "var"), it is visible outside the scope of ready(). See http://stackoverflow.com/questions/1013385/what-is-the-difference-between-a-function-expression-vs-declaration-in-javascrip for an explanation of the difference between function declaration and function expression – Vlad Mar 23 '16 at 14:52
4

Your function is defined within the scope of the $(document).ready() callback and cannot be seen from the outside. Either define the function outside the $(document).ready() scope of call it only from within.

Stefan Gehrig
  • 82,642
  • 24
  • 155
  • 189
2

Just another addition:

When declaring functions or variables inside of the $(document).ready() function, these are inaccessible when using onclick() binds in the document.

You can either move your declarations outside of $(document).ready(), or you can use $('#element').on('click', function() {}) within `$(document).ready().

Daniel Dewhurst
  • 2,533
  • 2
  • 21
  • 39
1
<script>
    $(document).ready(function(){
      myfnc = function (param1, param2)
      {
        alert('Hello');
      }
      myfnc();
    });
</script>
<input type="button" onclick="myfnc('arg1', 'arg2')" value="Click me">
Wilq
  • 2,245
  • 4
  • 33
  • 37
Hari Om
  • 11
  • 1