javascript syntax: function calls and using parenthesis

why does this work..

<script type="text/javascript">
<!-- 

function myAlert(){
    alert('magic!!!');
}


if(document.addEventListener){   
    myForm.addEventListener('submit',myAlert,false); 
}else{   
    myForm.attachEvent('onsubmit',myAlert); 
}
// -->
</script>

but not this ????

<script type="text/javascript">
<!-- 

function myAlert(){
    alert('magic!!!');
}


if(document.addEventListener){   
    myForm.addEventListener('submit',myAlert(),false); 
}else{   
    myForm.attachEvent('onsubmit',myAlert()); 
}
// -->
</script>

the difference being the use of parenthesis when calling the myAlert function.

the error I get..

"htmlfile: Type mismatch." when compiling via VS2008.


Solution 1:

The () after a function means to execute the function itself and return it's value. Without it you simply have the function, which can be useful to pass around as a callback.

var f1 = function() { return 1; }; // 'f1' holds the function itself, not the value '1'
var f2 = function() { return 1; }(); // 'f2' holds the value '1' because we're executing it with the parenthesis after the function definition

var a = f1(); // we are now executing the function 'f1' which return value will be assigned to 'a'
var b = f2(); // we are executing 'f2' which is the value 1. We can only execute functions so this won't work

Solution 2:

The addEventListener function expects a function or an object implementing EventListener as the second argument, not a function call.

When the () are added to a function name, it is a function invocation rather than the function itself.

Edit: As indicated in the other responses and in the comments, it is possible to return functions in Javascript.

So, for something interesting, we could try the following. From the original myAlert, we can change it a little to return a different message, depending on the parameters:

function myAlert(msg)
{
    return function()
    {
        alert("Message: " + msg);
    }
}

Here, notice that the function actually returns a function. Therefore, in order to invoke that function, the extra () will be required.

I wrote a little HTML and Javascript to use the above function. (Please excuse my unclean HTML and Javascript, as it's not my domain):

<script type="text/javascript">

function myAlert(msg)
{
    return function()
    {
        alert("Message: " + msg);
    }
}

</script>

<html>
<body>

<form>
<input type="button" value="Button1" onclick="myAlert('Clicked Button1')()">
<input type="button" value="Button2" onclick="myAlert('Clicked Button2')()">
</form>

</body>
</html>

Two buttons are shown, and each will call the myAlert function with a different parameter. Once the myAlert function is called, it itself will return another function so that must be invoked with an extra set of parenthesis.

End result is, clicking on Button1 will show a message box with the message Message: Clicked Button1, while clicking on Button2 will show a message box saying Message: Clicked Button2.

Solution 3:

When you use the parenthesis you're actually invoking the function and you're sending the function result (in this case undefined because myAlert doesn't have a return value) as the parameter.