views:

1420

answers:

5

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.

+2  A: 

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.

coobird
Yes, functions can return functions (as later answers show)
Justin Love
+10  A: 

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
Luca Matteis
Huh. "function() {return 1;}();" is a syntax error, but "(function() {return 1;}())" is not. Silly JavaScript and your seperate function statements and expressions...
Simon Buchan
@Simon: "function() {return 1;}();" is a syntax error only when not assigned to a variable.
Luca Matteis
+2  A: 

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.

CMS
A: 

It's also worth noting that functions are first-class objects. You can toss them around like any other object. Here's a nice concise example of why this is cool, from Wikipedia:

function makeDerivative( f, deltaX ) {
    var deriv = function(x) { 
       return ( f(x + deltaX) - f(x) )/ deltaX;
    }

    return deriv;
}

var cos = makeDerivative( Math.sin, 0.000001);
Tyson
A: 
if(document.addEventListener){   
    myForm.addEventListener('submit',myAlert(),false); 
}else{   
    myForm.attachEvent('onsubmit',myAlert()); 
}

using myAlert() here is giving the returned value of the function, not the function itself.

Consider this:

function bob() {
    return "hello world";
}

alert(bob());

the alert is going to use the value returned by the function bob.

If you want to pass additional parameters in you addEventListener, try this:

if(document.addEventListener){   
    myForm.addEventListener('submit',function(event) {
        myAlert(event,myOtherParamater); 
    },false); 
}else{   
    myForm.attachEvent('onsubmit',function () {
        myAlert(window.event,myOtherParameter); 
    }); 
}

javascript uses first-class functions and can thus be passed as parameters to functions which is what the addEventListener and attachEvent methods are expecting. Hope that helps.

Jonathan Fingland