То, что говорит Пекка, правильно, но я хочу немного уточнить пример, который поможет объяснить кому-то, кто не полностью понимает указатели на функции или делегаты.
Я не буду использовать, 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;
Теперь, в момент определения ret, retстановится вашей Multiplyфункцией, а не результатом, полученным от вашей Multiplyфункции. Вызовы в 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
Обратите внимание , как мы называем b()в наших cи dприсвоений точно так , как мы могли бы назвать currentTime()?