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