0

index.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="Script1.js"></script>
    <script src="Script2.js"></script>
</head>
<body>

</body>
</html>

Script1.js

var Main;
window.onload = Main;

Script2.js

function Main() {
    alert("foo");
}

If I throw a breakpoint @ var Main; and step through the code in WebStorm, it appears to:

  1. Load Script1.js.
  2. Load Script2.js.
  3. Call Main().

However it doesn't execute the statement alert("foo") in that function. Could someone explain what's going on in more detail?

  • NOTE: I realize you should avoid using onload.
  • NOTE: I realize I could re-order the scripts and it would show the alert.
  • NOTE: If I omit the statement var Main;, step 3 above does not occur.

Bonus: In WebStorm, it shows the value of the window.onload field as null and the value of Main as void. What is the difference between a value of null and void?

chopperdave
  • 526
  • 4
  • 12
  • 2
    While it's true that they're in the same global variable environment, the scripts are executed separately, and synchronously. This means that even though function declarations are indeed hoisted to the top of the variable environment, the hoisting will not occur until the script actually runs. So by the time the second script begins, the first has completed, and `window.onload` has been assigned the current value of `Main` which is `undefined`. –  Mar 11 '12 at 23:04
  • @amnotiam I understood that at the point `Main` is assigned to `window.onload` that `Main` is still `void`. However, when the second script loads, isn't it setting the value of `Main` to the function `Main()` and thus when the `window.onload` event fires, `Main` is now no longer `void` and instead refers to the `Main` function established as part of loading the second script? – chopperdave Mar 12 '12 at 00:12
  • @chopperdave yes, `Main` is a function in the second script, but it doesn't change the fact that `window.onload` is set to `undefined` (not `void`, `void` is not a value). The above comment is really the best answer here. – Dagg Nabbit Mar 12 '12 at 00:21
  • @chopperdave: JavaScript is entirely *"by value"*... *(keeping in mind that in the case of object types, the value is a pointer to the object)*. If JavaScript was a *"by reference"* language, then yes, the `onload` property would hold a reference to the `Main` variable, and would observe its changes. But because it's a *"by value"* language, the value `undefined` is given to `.onload`, and `.onload` is entirely unaware of what happens to the `Main` variable thereafter. –  Mar 12 '12 at 00:23
  • I think my confusion here is with 'void' vs 'null' vs 'undefined'. For some reason, this IDE doesn't use the term 'undefined' and instead uses 'void' and 'null' as values. Based on the response form the guy below, my guess is that the IDE is using 'void' instead of 'undefined'. Is it expected that when loading the scripts that the value of `window.onload` should be 'null'? – chopperdave Mar 12 '12 at 00:52
  • For this purpose, I don't really think it matters. It depends on the context. Some implementation may give a message stating *"window.onload is null or undefined"* or something similar. The `undefined` value is simply a default for all variables and properties. The `null` value needs to be assigned. Implementations may assign a `null` default to some of their additions to the environment like `window.onload`. Main point is that neither is a function. I assume you ultimately wanted to know why `window.onload` didn't reference the `Main` function. –  Mar 12 '12 at 01:16
  • FYI, `null === undefined; // false` but `null == undefined; // true` They're distinct types, but they do coerce to each other given the algorithm used by `==`. –  Mar 12 '12 at 01:18

2 Answers2

1

The contents of Script1.js:

var Main; // declare but do not initialize a variable named "Main"
window.onload = Main; // sets the onload handler to that *undefined* variable

the function named Main is simply never called.


As for the bonus question: What is the point of void operator in JavaScript? and void @ MDC. TL;DR: void is an operator which always returns undefined. Do you understand the difference between null and undefined?

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • If I step through the code @ runtime, the function `Main` **IS** being called but the statements inside of it are not be executed. That may not be the correct language to describe what's occuring, but the debugger clearly shows those three separate events occuring (load script1, load script2, call Main). – chopperdave Mar 12 '12 at 00:14
  • Yes, it's _trying_ to call `Main`, because you have assigned a value to `window.onload`. That doesn't mean it's calling the `Main` function defined in `Script2.js`. – Matt Ball Mar 12 '12 at 00:22
  • Also, when I mentioned 'void', I didn't mean in the sense I think you are describing. I meant 'void' in the sense that the WebStorm IDE is displaying it. In the IDE, a variable can have a VALUE of 'null' or 'void'. Perhaps by 'void' they actually are referring to 'undefined' ? – chopperdave Mar 12 '12 at 00:25
  • It's possible that the debugger shows `void` as the function's return value - that is, it does not return anything. As for the function `Main` being called: change `Main` to `Foo` in `Script1.js` but not `Script2.js` and you'll see that it's the `window.onload` handler being called; the `Main` in `Script2.js` is just dead code. – Matt Ball Mar 12 '12 at 01:06
1

Because Main is an empty variable at that point in script 1. window.onload essentially is set to undefined. window.onload expects a callback function like so...

var Main = function() { my_main_function() }
Daniel Doezema
  • 1,592
  • 10
  • 13