Я заметил разницу при вызове функции с пустыми круглыми скобками или без каких-либо скобок. Тем не менее, я не передаю какие-либо аргументы функции, поэтому я задавался вопросом, в чем бы заключалась разница между:
Пожалуйста, объясните принцип, лежащий в его основе.
Ответ 2
То, что говорит Пекка, является правильным, но я хочу немного пояснить пример, который поможет объяснить кому-то, кто не полностью понимает указатели функций или делегатов.
Я не буду использовать 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
, чем о вашей собственной функции. Только немного отличается то, что он вызывается окном при его загрузке. [Отказ от ответственности: я никогда не отказывался от оконных функций, поэтому я не уверен, что это вызовет негативные последствия. Можно было бы надеяться, что они проведут проверку, назначена ли функция перед вызовом i.e. 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()
?
Ответ 5
Я опаздываю на 6 лет, но я чувствую, что это могло быть объяснено намного проще, чем приведенные выше ответы.
Итак, вот TL;DR; или птичий глаз при вызове функций, использующих и не использующих ()
Возьмем эту функцию, например:
function foo(){
return 123;
}
, если вы запишете "foo" - без ()
console.log(foo);
---outout------
function foo(){
return 123;
}
Использование ()
означает выборку самой функции. Вы бы сделали это, если хотите, чтобы он передавался как обратный вызов.
, если вы запишете "foo()" - с помощью ()
console.log(foo());
-----output-----
123
Использование ()
после того, как функция означает выполнение функции и вернуть значение.