调用函数时加上括号后函数不执行(即使它不需要参数)

3
这是一个用来警示我标签的childNodes数量的函数。
    function countBodyChildren() {
      var body_element = document.getElementsByTagName("body")[0];
      alert(body_element.childNodes.length);
}

 window.onload = countBodyChildren;

该函数可以正常运行,但是当我在函数名后面添加()时,即window.onload = countBodyChildren();,函数就不能正常运行了。为什么会这样呢?我认为调用函数时,即使它们不需要任何参数,也总是要在函数名后面加上()

3个回答

9
我认为即使函数不需要任何参数,您仍然需要在其名称后面添加()来调用函数。

您的想法是正确的。但是,在这里,您不希望调用函数;您要告诉浏览器在适当的时候调用哪个函数。

当您添加括号时,将立即调用该函数(而不是在加载时)。该函数执行;尝试查找body元素,但还没有加载任何元素;因此,您的body_element最终变成了undefined。您在undefined上查找childNodes,并收到错误。window.onload赋值不会发生。

即使您的函数没有引发错误,它也将返回undefined,因此window.onload变为undefined,因此当页面最终加载时什么都不会发生。

相反,您需要开始思考函数只是另一种类型的值。当您说

function a() {
  // ...
}

这与以下内容相同:

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

实际上有一些重要的区别,但现在它们并不重要;当你掌握了基础知识后再去查找。一个函数现在被“包含”在变量a中。然后你可以这样做:

var b = a;
b();

这将会起作用 - 你将原来的函数a赋值给变量b,然后通过调用新名称(因为现在ab都引用同一个函数)来执行它。同样地,在之后的操作中,

window.onload = countBodyChildren;

window对象的onload属性现在包含了您的函数。当页面加载完成时,浏览器将执行其中的任何内容。

您遇到了过早执行的情况。


1

window.onload = countBodyChildren();

这句话的意思是“调用函数,并将函数的返回值分配给窗口对象的onload属性。你的函数没有返回值。

例如:

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

这会将5分配给onload属性。这不是你想要的。你需要将一个函数引用分配给onload属性,这样js引擎就可以在事件发生时调用该函数。


1

window.onload 期望的是一个函数或函数定义的引用。

当您放置括号时,实际上执行该函数,并且函数的返回值被分配给 window.onload


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接