In JavaScript, does it make a difference if I call a function with parentheses?
Asked Answered
P

5

109

I noticed a difference when calling a function with empty parentheses, or without any parentheses at all. However, I am not passing any arguments to the function so I wondered, what would be the difference between:

window.onload = initAll();

and

window.onload = initAll;

Please explain the principle behind it.

Perpend answered 14/7, 2010 at 14:6 Comment(14)
The () characters are called "parentheses". "Brackets" refers to []. I edited your post to conform.Follower
@JS Bangs - Only in US English; not elsewhere. Although programmers tend to call them "parentheses" to avoid confusion, in UK English the rounded ones are known simply as brackets. The square ones are known as "square brackets". en.wikipedia.org/wiki/BracketSivia
in programming the () are definitely NOT brackets, never had been regardless of locale of the programmer. And for completeness [] are brackets and {} are braces.Homage
@fuzzy lollipop - I was just going on the common language I hear developers at all levels use every day and have done for years. If you say "brackets" in the UK, everyone, programmers alike, will think of parenthesis, not square brackets. If you mean "[]", you would have to say square brackets. That's just the way it is.Sivia
on a serious note, the official UNICODE name is Parenthesis. 0028 ( LEFT PARENTHESIS = opening parenthesis (1.0) and 0029 ) RIGHT PARENTHESIS = closing parenthesis (1.0) -- unicode.org/charts/charindex.html#P and what Dictionary.com has to say about it -- dictionary.reference.com/browse/PARENTHESIS "Either or both of the upright curved lines, ( ) ..."Homage
So this isn't just an "US English" thing, it is an International standard definition because UNICODE is an International Standard.Homage
@fuzzy - Where do you get your facts from, seriously? {} are called squirrelly brackets.Pore
It is amazing this post got 12+ up votes? initAll() is the result of the function intAll is the function itself. That is basic JavaScript.Impeachment
@fuzzy lollipop - Unicode is an international standard on encoding characters as bytes, not on naming. The authors of the unicode document are not claiming the given name for a character is an international standard. It is the code vs. the character they are defining. But, you might like to note that they also refer to [ and ] as square brackets - (not just "brackets"), and that they refer to all of [, { and ( as bracketing characters. You should strive to understand the nuances in the way different places use the same words. Very important if you are part of an international team.Sivia
brackets might be a class of surrounding characters like your link to the wikipedia article states that () are still parenthesis, proving my point for me. And my point exactly is semantics are important, in programming they are called paranethesis, to semantically disambiguate them from the other "brackets". I guess you refer to & as a symbol and not an ampersand as well? Same line of reasoning. All IDE's preferences refer to () as parenthsis and [] as brackets and {} as braces. And the offical UNICODE name is parenthsis for those characters and all the other "bracket" like curved.Homage
So to my point you should refer to them by the un-ambiguous names, Internationally just like UNICODE does and every IDE does. vertigrated.com/images/prefs.pngHomage
Agreed - it is better to refer to () as parenthesis to avoid ambiguity - I said that programmers tend to in my 1st comment. However, there is nothing more ambiguous than expecting people to use language in a way that is at odds with what they are used to. If you mean "[]" in the UK you'll have to say square brackets. And if someone says "brackets", everyone will assume round ones, not square ones. It matters, for purposes of clarity, not one jot what any standard says if people don't follow it. I'm sure if you look through all the Unicode standard you'll spot your own examples of this too.Sivia
You have to understand that most languages and standards are biased heavily towards US English. The moment you leave US English as the primary language, things get a lot more ambiguous. Things that are dead set standards in US English can go against the way the rest the the English speaking world have been taught, not to mention other languages. If you want to be clear and unambiguous, then use language that won't be misunderstood by anyone. Parenthesis - fair enough. Brackets instead of square brackets, forget it.Sivia
Related: What is the difference between a function call and function reference?.Periodical
C
167
window.onload = initAll();

This executes initAll() straight away and assigns the function's return value to window.onload. This is usually not what you want. initAll() would have to return a function for this to make sense.

window.onload = initAll;

this assigns the actual function to window.onload - this is possible because in JavaScript, as @Felix says, functions are first class objects - without executing it. initAll will be executed by the load event.

You may also see something like this:

window.onload = () => initAll();

This will create a new function that, when called, will call initAll immediately. Parentheses are necessary here for that "call initAll immediately" part to work. But, because it's wrapped in a function, nothing will execute until that outer function itself is called, and you assign the reference of that outer function to window.onload, so initAll will also be executed on the load event.

Castaway answered 14/7, 2010 at 14:9 Comment(1)
Important to mention here is that functions are first class objects in JavaScript.Ejaculatory
B
141

What Pekka says is correct, but I want to elaborate a little with an example that will help explain to someone who doesn't fully understand function pointers or delegates.

I won't use window.onload because that's a bit contrived to demonstrate. I'll use a simple multiply function to demo instead:

function Multiply(operator, operand) {
    return operator * operand;
}

This could equally be written:

Multiply = function(operator, operand) {
    return operator * operand;
}

While in the first example, the implication may not be obvious, the second example shows more clearly that we're assigning a function which has 2 parameters to a variable called Multiply, and this concept of functions as assignments is common throughout JavaScript. This is a small demonstration of the fact that functions are "first class citizens", that is, they can be passed around exactly as if we were passing around values.

So now to the difference of assignment:

var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);

At the point of defining the ret variable, Multiply is executed and the return value is assigned - ret becomes equal to 12.

Let's try that again a different way:

var operator = 3;
var operand = 4;
var ret = Multiply;

Now, at the point of defining ret, ret becomes your Multiply function as opposed to being the result obtained from your Multiply function. Calls to ret() will cause your Multiply function to be executed, and you can call it exactly as if you'd called Multiply(operator, operand):

var out = ret(3, 4);

is the same as

var out = Multiply(3, 4);

You have effectively said that you are going to use ret as a delegate for Multiply(). When calling ret, we're really referring to the Multiply function.

Back to your window.onload. Think of this as:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

initAll = function() {
    return 12;
}

So as you can see, window.onload is a function just like any other function, there's nothing special about it. You can assign it a value, assign it a function, null it out if you wish - the point is that there's nothing any more special about window.onload than there is about your own function. The only slightly different thing is that it gets called by the window when it's loaded. [Disclaimer: I've never actually nulled out window functions, so I'm not sure if this will cause negative repercussions. One would hope they check to see if a function is assigned before calling it i.e. if (window.onload) window.onload();].

Now calling initAll() what we're saying is:

window.onload = initAll();

which might as well say:

window.onload = 12;

But when we say initAll without the parentheses, what we're really saying is: I want to replace whatever my window.onload function is, with a new function - i.e. I want to replace it with my initAll function, so that any calls to window.onload runs my initAll code.

So:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

is replaced with:

window.onload = function() {
    return 12;
}

So any call to window.onload will execute your initAll function instead of whatever window.onload was originally. You have replaced the original function with your new function.

In fact, you could equally write:

window.onload = function() {
    //Write all your init code right in here instead of having a separate 
    //initAll function.
}

Another example that may demonstrate better is this:

var d = new Date();
var currentTime = d.getTime();

Whatever the time was at the time d is defined ends up assigned to currentTime. Great, but that's only useful if we want to find out what time the function containing that code was called - i.e. at page load time. What if we want the current time any time that currentTime is called?

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

Notice how we call b() in our c and d assignments exactly as we could call currentTime()?

Bust answered 14/7, 2010 at 14:6 Comment(1)
Hey, what if I want to add a function that takes arguments on an event listener?Clustered
M
17

Functions in javascript are first-class citizens, and as such, can be assigned to other variables or passed around as arguments.

So, when you do

window.onload = initAll;

You are setting the onload property of the window object to reference the initAll function itself.

When you do

window.onload = initAll();

You are setting the onload property to hold the return value of initAll, since it will execute in place on that line.

Mabe answered 14/7, 2010 at 14:11 Comment(0)
H
13

I'm 6 years late but I feel this could have been explained a lot simpler than the above answers.

So here is the TLDR; or bird's eye view when calling functions using and not using ()'s

Lets take this function for example:

function foo(){
return 123;
}

if you log "foo" - without ()

console.log(foo); 

---outout------
function foo(){
return 123;
}

Using no () means to fetch the function itself. You would do this if you want it to be passed along as a callback.


if you log "foo()" - with ()

console.log(foo());
-----output-----
 123

Using () after a function means to execute the function and return it's value.

Horrendous answered 14/7, 2016 at 0:43 Comment(0)
Y
12

initAll is a reference to a function value and the brackets operator appended to the function name RUNS this function object.

So if you do something like

a = initAll

then a will become the same as initAll - for example you can do a() - but with

a = initAll()

the variable a will get the return value of the executed initAll function

Yellowthroat answered 14/7, 2010 at 14:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.