Синтаксис javascript: вызовы функций и использование скобок

почему это работает ..

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

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


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

а не это ????

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

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


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

разница заключается в использовании круглых скобок при вызове myAlert функции.

я получаю ошибку ..

"htmlfile: Несоответствие типов". при компиляции через VS2008.

Ответов (5)

Решение

Знак () после функции означает выполнение самой функции и возврат ее значения. Без него у вас просто есть функция, которую может быть полезно передать в качестве обратного вызова.

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

Также стоит отметить, что функции являются первоклассными объектами. Вы можете бросать их, как любой другой предмет. Вот хороший и краткий пример того, почему это круто, из Википедии :

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

    return deriv;
}

var cos = makeDerivative( Math.sin, 0.000001);

Когда вы используете круглые скобки, вы фактически вызываете функцию и отправляете результат функции (в данном случае undefined, потому что myAlert не имеет возвращаемого значения) в качестве параметра.

Функция addEventListener ожидает, что в качестве EventListener второго аргумента будет реализована функция или объект, а не вызов функции.

Когда () добавляются к имени функции, это вызов функции, а не сама функция.

Изменить: как указано в других ответах и ​​в комментариях, можно возвращать функции в Javascript.

Итак, для чего-нибудь интересного мы могли бы попробовать следующее. Из оригинала myAlert мы можем немного изменить его, чтобы возвращать другое сообщение, в зависимости от параметров:

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

Обратите внимание, что функция фактически возвращает функцию. Следовательно, чтобы вызвать эту функцию, () потребуется дополнительная функция .

Я написал немного HTML и Javascript, чтобы использовать указанную выше функцию. (Прошу прощения за мой нечистый HTML и Javascript, так как это не мой домен):

<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>

Показаны две кнопки, каждая из которых вызывает myAlert функцию с другим параметром. После вызова myAlert функция сама вернет другую, function поэтому ее нужно вызывать с дополнительным набором круглых скобок.

Конечный результат: нажатие на Button1 отобразит окно сообщения с сообщением Message: Clicked Button1, а нажатие на Button2 отобразит окно сообщения с сообщением Message: Clicked Button2 .

if(document.addEventListener){   
    myForm.addEventListener('submit',myAlert(),false); 
}else{   
    myForm.attachEvent('onsubmit',myAlert()); 
}

использование myAlert() здесь дает возвращаемое значение функции, а не саму функцию.

Учти это:

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

alert(bob());

предупреждение будет использовать значение, возвращаемое функцией bob .

Если вы хотите передать дополнительные параметры в addEventListener, попробуйте следующее:

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

javascript использует функции первого класса и, таким образом, может передаваться в качестве параметров функциям, чего ожидают методы addEventListener и attachEvent. Надеюсь, это поможет.