To, co mówi Pekka, jest poprawne, ale chciałbym trochę rozwinąć przykład z przykładem, który pomoże wyjaśnić komuś, kto nie w pełni rozumie wskaźniki funkcji lub delegatów.
Nie użyję, window.onloadponieważ jest to trochę wymyślone, aby pokazać. Zamiast tego użyję prostej funkcji mnożenia do demonstracji:
function Multiply(operator, operand) {
return operator * operand;
}
Można to również napisać:
Multiply = function(operator, operand) {
return operator * operand;
}
Podczas gdy w pierwszym przykładzie implikacja może nie być oczywista, w drugim przykładzie wyraźniej widać, że przypisujemy funkcję, która ma 2 parametry do zmiennej o nazwie Multiply, a koncepcja funkcji jako przypisań jest powszechna w całym JavaScript. To mały dowód na to, że funkcje są „obywatelami pierwszej kategorii” , to znaczy można je przekazywać dokładnie tak, jakbyśmy przekazywali wartości.
A teraz do różnicy przydziału:
var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);
W momencie definiowania zmiennej ret Multiplyzostaje wykonana i przypisana wartość zwracana - retstaje się równa 12.
Spróbujmy jeszcze raz w inny sposób:
var operator = 3;
var operand = 4;
var ret = Multiply;
Teraz, w momencie definiowania ret, retstaje się twoją Multiplyfunkcją, a nie wynikiem uzyskanym z twojej Multiplyfunkcji. Wywołania do ret()spowodują wykonanie Twojej Multiplyfunkcji i możesz ją wywołać dokładnie tak, jakbyś zadzwonił Multiply(operator, operand):
var out = ret(3, 4);
jest taki sam jak
var out = Multiply(3, 4);
Skutecznie powiedziałeś, że zamierzasz użyć go retjako delegata Multiply(). Dzwoniąc ret, naprawdę odnosimy się do Multiplyfunkcji.
Wracając do twojego window.onload. Pomyśl o tym jako:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
initAll = function() {
return 12;
}
Jak więc widzisz, window.onloadjest to funkcja jak każda inna funkcja, nie ma w niej nic specjalnego. Możesz przypisać mu wartość, przypisać mu funkcję, anulować ją, jeśli chcesz - chodzi o to, że nie ma nic bardziej specjalnego window.onloadniż twoja własna funkcja. Jedyną nieznaczną różnicą jest to, że jest wywoływany przez okno po załadowaniu. [Zastrzeżenie: tak naprawdę nigdy nie anulowałem funkcji okna zewnętrznego, więc nie jestem pewien, czy spowoduje to negatywne reperkusje. Można mieć nadzieję, że sprawdzą, czy funkcja jest przypisana przed jej wywołaniem, tj if (window.onload) window.onload();.].
Teraz initAll()nazywamy to, o czym mówimy:
window.onload = initAll();
który równie dobrze mógłby powiedzieć:
window.onload = 12;
Ale kiedy mówimy initAllbez nawiasów, tak naprawdę mówimy: chcę zastąpić jakąkolwiek moją funkcję window.onload, nową funkcją - tj. Chcę zastąpić ją moją initAllfunkcją, aby wszelkie wywołania window.onloaduruchamiały moją initAllkod.
Więc:
window.onload = function() {
//Doing what all good window.onload functions should do...
}
zastępuje się:
window.onload = function() {
return 12;
}
Więc każde wywołanie window.onloadto wykona twoją initAllfunkcję zamiast tego, co window.onloadbyło pierwotnie. Zastąpiłeś oryginalną funkcję nową funkcją.
W rzeczywistości, mógłby równie napisać:
window.onload = function() {
//Write all your init code right in here instead of having a separate
//initAll function.
}
Innym przykładem, który może pokazać lepiej, jest:
var d = new Date();
var currentTime = d.getTime();
Niezależnie od tego, jaki czas był w tym czasie, djest przypisany currentTime. Świetnie, ale jest to przydatne tylko wtedy, gdy chcemy dowiedzieć się, o której godzinie została wywołana funkcja zawierająca ten kod - tj. W czasie ładowania strony. A co, jeśli chcemy, aby w dowolnym momencie currentTimewywoływano aktualny czas ?
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
Zauważ, jak wzywamy b()nasze ci dzadania dokładnie tak, jak moglibyśmy to nazwać currentTime()?