Jump to content
Larry Ullman's Book Forums

Recommended Posts

I consider myself somewhat decent at JS, but I have never understood the following:

 

If I declare the following, all is well and good:

 

var init;

window.onload = init;

function init() {

 // Exciting stuff here!

}

 

However, if I change the function definition as follows, it will not work:

 

var init;

window.onload = init;

init = function () {

 // Exciting stuff here!

};

 

However, if I simply place the window.onload line below the function definition (as follows), then it works fine:

 

var init;

init = function () {

 // Exciting stuff here!

};

window.onload = init;

 

Does anyone know what's up with this? It seems like some quirk in the JS specs, if anything. As far as I know, function init() and init = function () are the same meaning. Am I missing something big?

 

Thank you.

Link to post
Share on other sites

I would say you're well more than "decent" at JavaScript! I would start by saying, however, that I probably would never do any one of these approaches. It's dangerous to have a variable and a function with the same name (this is more true in JavaScript where both can be objects). And with an init function, there's not much benefit to creating it as a variable as it probably won't be used more than once. In any case, the problem in the second code is that you're associating a variable with no value to window.onload. In the first example, it's not a problem because of the way that the JS engine parses the code. You can call functions before they're defined in code because the JS engine will implement all the JS function definitions first, before executing the other code.

Link to post
Share on other sites

Actually, I use JSLint to check all my JS, and it pretty much requires that you declare all functions before you call them. And just about the only way this is possible most of the time is by declaring them in the variable list at the top of your code.

 

As you know, functions are objects in JS, which makes them a variable like any other variable in JavaScript. To that end, functions can be assigned to variables, just like anything else. I know for a fact that the following are the same thing:

 

function sum(a, c) {

 return a + c;

}

sum = function (a, c) {

 return a + c;

};

 

As such, the following works perfectly fine (and according to Douglas Crockford and JSLint is good practice):

 

var foo = 4,
 bar = 9,
 sum = function (a, c) { return a + c; },
 total = sum(foo, bar);

alert(total); // 13

 

Anyway, I think you're right in that, for whatever reason, the JS engine parses the function keyword differently from normal variable assignments, which is the case with the second function definition above.

 

Well, I'll leave it at that, but I found it to be rather interesting. I suppose normal variable assignments, even if they are functions, go in a normal, top-down fashion, and you can't assign an undefined variable to an event.

 

Edit: Dear Larry, I couldn't use the variable 'b' above, because your stupid forum told me that 'b_)' (without the underscore) is an emoticon, and I had too many in my post. Please eliminate this behavior.

Link to post
Share on other sites
Well, I'll leave it at that, but I found it to be rather interesting. I suppose normal variable assignments, even if they are functions, go in a normal, top-down fashion, and you can't assign an undefined variable to an event.

 

Yes, that's the point I was trying to make, just not as efficiently or clearly.

 

Link to post
Share on other sites

I know this issue is kind of cleared up but just explain a little more if you're interested. Your first example and second example are not the same - there are subtle nuances between the two. The first is considered in ECMA script as a function declaration while the second is considered a function expression. The differences are explained in the ECMA script spec.

 

Basically (as you've described above) function declarations are parsed and evaluated before any other expressions are - irrespective of where that declaration is positioned in the source code. Another interesting point I found out today is that a function declaration cannot appear 'in block' e.g. within IF conditionals or any loops. Although they may work their implementation cross browser is not guaranteed in accordance with ECMAScript - this is where function expressions should be used.

 

So not a quirk of the JS engine but intentional apparently.

Link to post
Share on other sites

And furthermore, function expressions should also not be used in for loops, as it can cause a huge stack of functions in memory.

 

Instead, it's best to call a function in a for loop that contains all the function expressions.

 

And Stuart, yes, you are right. There are multiple ways of declaring functions, and there are subtle differences between them all, which I should have noted, as that is indeed the crux of why one method works, but not the other.

 

Thank you Larry and Stuart for clarifying things.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...