简体   繁体   中英

Newbie Javascript: Function doesn't run when calling it with added parenthesis (even though it doesn't need parameters)

Here's my function to alert me of the number of childNodes of the body tag.

    function countBodyChildren() {
      var body_element = document.getElementsByTagName("body")[0];
      alert(body_element.childNodes.length);
}

 window.onload = countBodyChildren;

The function runs fine, but when I add () to the end of the function name ie window.onload = countBodyChildren(); the function does not run. Why is this? I thought to call functions, even if they don't need any parameters, you always add the () to the end of its name.

I thought to call functions, even if they don't need any parameters, you always add the () to the end of its name.

You thought correctly. But here, you don't want to call the function; you want to tell the browser which function to call when the time comes.

When you add the parentheses, you will call the function, immediately (not on load). The function executes; tries to look up the body elements, but there is none loaded yet; so you body_element ends up as undefined . You look up childNodes on undefined , and get an error. window.onload assignment does not happen.

Even if your function did not throw an error, it would have returned undefined , so window.onload becomes undefined , so nothing happens when the page is finally loaded.

Instead, you need to start thinking that functions are just another kind of value. When you say

function a() {
  // ...
}

it is the same as this:

a = function() {
  // ...
};

(Actually there are differences, important ones, but they're irrelevant for now; look them up when you have the basics down pat). A function is now "contained" in variable a . Then you can do this:

var b = a;
b();

and it will work - you're putting whatever was in a (your function) into the variable b , and then executing it by invoking its new name (since now both a and b refer to the same function). In the same way, after

window.onload = countBodyChildren;

the onload property of the window object now contains your function. Browser will then execute whatever is there when the load finishes.

You had a case of premature execution.

What window.onload expects is a reference to a function or a function definition.

When you put parenthesis, you actually execute the function and it is the return value of the function that is assigned to window.onload .

window.onload = countBodyChildren();

That says "call the function, and assign the return value of the function to the onload property of the window object. Your function returns nothing.

For example

function countBodyChildren() {
      var body_element = document.getElementsByTagName("body")[0];
      alert(body_element.childNodes.length);
return 5;
}
window.onload = countBodyChildren();

that would assign 5 to the onload prop. Not what you want. you need to assign a function reference to the onload prop, so the js engine can call the function when the event occurs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM