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