1

I have a massive javascript file with many function expressions. All of a sudden console gives me the following errors:

In IE

The value of the property 'myFunc' is null or undefined, not a Function object

In Firefox

TypeError: myFunc is not a function

This is how I call the function:

myFunc();

This is the function:

myFunc = function() {
  //do stuff
}

This is happening on ALL function expressions. If I change one to a function declaration it works, but then will fail on some other function expression call inside of it. What the heck?

Jonathan Eckman
  • 2,071
  • 3
  • 23
  • 49
  • So do you still get the error without calling `myFunc`? Or does it only occur after you call it? – Ian Sep 25 '12 at 15:49
  • @ianpgall If I comment out all calls to a function expression on the page I get no errors. So no. – Jonathan Eckman Sep 25 '12 at 15:52
  • "All of a sudden console gives me the following errors..." All of a sudden? No, something changed. Look for what you changed. – Steve Wellens Sep 25 '12 at 15:54
  • @SteveWellens My files are identical to files that work fine in another environment. Compared them using a tool in Visual Studio. – Jonathan Eckman Sep 25 '12 at 15:57
  • Do you have any closures in your script file? I know if you don't use semicolons between closures and other things, the closure attempts to call the previous thing. – Ian Sep 25 '12 at 16:01
  • 1
    The difference between `myFunc = function() {` and `function myFunc() {` is scope: the latter *declares* `myFunc`, which the former doesn't bother to do. This can affect name resolution. – ruakh Sep 25 '12 at 16:06

1 Answers1

2

Possibility 1

If you are calling the function expression before it is defined, you will get this error. If you however turn it into a function declaration, the function declaration would get hoisted to the top of the scope, and could be called before or after the actual declaration occurs. So:

functionFoo();
var functionFoo = function() {

};

Will give this error, because you are trying to call the function before it is defined. But:

functionFoo();
function functionFoo() {

}

Will work, because actual function declarations are hoisted to the top of the scope, and can be used anywhere.

Possibility 2

If you are calling the function expression from a different scope that is outside where the function expression is defined, you will get this error. function expressions, like other variables, can only be used within the scope they are defined. So:

$( document ).ready( function() {
   var functionFoo = function() {

   };
} );
functionFoo();

Will give you an error, because the defining of the function happens in a different scope than the call. But:

$( document ).ready( function() {
   var functionFoo = function() {

   };
   functionFoo();
} );

Will work just fine, because both the defining and the call happen in the same scope.

dqhendricks
  • 19,030
  • 11
  • 50
  • 83
  • So if I have `myFunc = function() {};` in my included js file and call `$(document).ready(function(){ myFunc(); });` in the page that that includes that js file, I will get this error due to scope? – Jonathan Eckman Sep 25 '12 at 17:46
  • I notice you use `var` in each function expression, as does the mdn. Is this required? – Jonathan Eckman Sep 25 '12 at 18:04
  • @Feature For the first question, it depends. If you are defining the function expression in the global scope, and the external javascript gets loaded before the DOM is ready, then it will work, because the ready function inherits the parent (global) scope in which it was defined. If one piece of code depends in an external file relies on another peice of code in another external file, it would be good practice to use an AMD compliant loader like require.js, where it waits until all dependencies are loaded before running the code that is dependent on them. – dqhendricks Sep 25 '12 at 18:21
  • @Feature For the second question, it is good practice to use the var keyword when defining a variable. If you're in the global scope, then there's no difference between using or not using the var keyword. If you're in a function scope then "var" will create a local variable in the functions scope, while "no var" will look up the scope chain until it finds the variable or hits the global scope (at which point it will create it). – dqhendricks Sep 25 '12 at 18:23