我注意到在调用带有空括号或根本没有任何括号的函数时会有所不同。但是,我没有向该函数传递任何参数,所以我想知道,它们之间有什么区别:
window.onload = initAll();
和
window.onload = initAll;
请解释其背后的原理。
原文由 Dean 发布,翻译遵循 CC BY-SA 4.0 许可协议
我注意到在调用带有空括号或根本没有任何括号的函数时会有所不同。但是,我没有向该函数传递任何参数,所以我想知道,它们之间有什么区别:
window.onload = initAll();
和
window.onload = initAll;
请解释其背后的原理。
原文由 Dean 发布,翻译遵循 CC BY-SA 4.0 许可协议
Pekka 所说的是正确的,但我想通过一个示例详细说明一下,这将有助于向不完全理解函数指针或委托的人进行解释。
我不会使用 window.onload
因为这有点人为地证明。我将使用一个简单的乘法函数来演示:
function Multiply(operator, operand) {
return operator * operand;
}
这同样可以写成:
Multiply = function(operator, operand) {
return operator * operand;
}
虽然在第一个示例中,暗示可能并不明显,但第二个示例更清楚地表明我们正在将一个具有 2 个参数的函数分配给一个名为 Multiply
的变量,并且函数作为赋值的概念是在整个 JavaScript 中很常见。这是函数是 “一等公民” 这一事实的一个小例子,也就是说,它们可以像传递值一样传递。
所以现在要区分分配:
var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);
在定义ret变量的时候, Multiply
被执行,返回值赋值 ret
等于12。
让我们以不同的方式再试一次:
var operator = 3;
var operand = 4;
var ret = Multiply;
Now, at the point of defining ret
, ret
becomes your Multiply
function as opposed to being the result obtained from your Multiply
function.调用 ret()
将导致执行你的 Multiply
函数,你可以像调用 Multiply(operator, operand)
一样调用它:
var out = ret(3, 4);
是相同的
var out = Multiply(3, 4);
您实际上已经说过,您将使用 ret
作为 Multiply()
的代表。当调用 ret
时,我们实际上指的是 Multiply
函数。
回到你的 window.onload
。把这个想象成:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
initAll = function() {
return 12;
}
正如您所见, window.onload
是一个函数,就像任何其他函数一样,没有什么特别之处。您可以为它分配一个值,为它分配一个函数,如果您愿意,可以将其设为空 - 重点是 window.onload
没有什么比你自己的函数更特别的了。唯一略有不同的是它在加载时被窗口调用。 [免责声明:我从来没有真正取消窗口函数,所以我不确定这是否会造成负面影响。人们希望他们在调用函数之前检查是否分配了一个函数,即 if (window.onload) window.onload();
]。
现在调用 initAll()
我们要说的是:
window.onload = initAll();
这还不如说:
window.onload = 12;
但是当我们说 initAll
时没有括号,我们真正想说的是:我想用一个新函数替换我的 window.onload 函数 - 即我想用我的 initAll
函数,以便任何调用 window.onload
运行我的 initAll
代码。
所以:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
被替换为:
window.onload = function() {
return 12;
}
因此,对 window.onload
的任何调用都将执行你的 initAll
函数,而不是原来的 window.onload
函数。您已经用新函数替换了原始函数。
事实上,你同样 可以这样 写:
window.onload = function() {
//Write all your init code right in here instead of having a separate
//initAll function.
}
另一个可能更好地证明的例子是:
var d = new Date();
var currentTime = d.getTime();
无论当时是什么时候 d
被定义最终分配给 currentTime
。很好,但这只有在我们想知道调用包含该代码的函数的时间时才有用——即在页面加载时。如果我们想要调用 currentTime
的任何时间的当前时间怎么办?
var currentTime = function() {
var d = new Date();
return d.getTime();
}
var a = currentTime(); //The current time at the point a is defined...
var b = currentTime; //b is a functional reference to currentTime...
var c = b(); //The current time when variable c is defined
var d = c; //The current time when variable c was defined
Notice how we call b()
in our c
and d
assignments exactly as we could call currentTime()
?
原文由 BenAlabaster 发布,翻译遵循 CC BY-SA 3.0 许可协议
13 回答13k 阅读
7 回答2.2k 阅读
3 回答1.3k 阅读✓ 已解决
6 回答1.3k 阅读✓ 已解决
2 回答1.4k 阅读✓ 已解决
3 回答1.4k 阅读✓ 已解决
6 回答1.1k 阅读
”`
这将创建一个新函数, 调用时 将 立即 调用
initAll
。这里括号是必要的,因为“ _调用initAll
立即_”部分起作用。但是,因为它被包装在一个函数中,所以在调用外部函数本身之前什么都不会执行,并且您将该外部函数的引用分配给window.onload
,所以initAll
也将被执行在加载事件上。