سؤال

My question is easiest explained with the code block and the questions below it.

But here is an attempt to explain my question in English:

I am learning JavaScript (and I am lazy so I use a lot of jQuery... ;) ) and I came across something which I don't quite understand, and I don't know what it is called, therefore I don't know what terms i should research.

Basically I am wondering when it is necessary to use function(){ ... } (without a name) and when to use function function_name(){ ... } (with a name), and how to execute a function with things like .click() .post() or setTimeout().

I know a couple of jQuery functions, like .click() that require you to put in a function to be called. But the thing is, you can't just say .click( function_name() ) (this would call the function immediately upon executing the script if I interpreted my test results correctly) instead you have to do .click( function(){ ... }) or you can do .click( function function_name(){ ... }). I also found out that you can say .click( function_name ) as long as you define beforehand var function_name = function function_name(){ ... } whereas the function name is optional, it will work with or without adding that.

I made an example with all possible scenarios I could think of. And I did find out what is working and what isn't, now I want to find out why each one is working and others aren't.

I am hoping understanding this will help me better understand asynchronous functions such as .post() or setTimeout().

<button id="one">Button 1</button>
<button id="two">Button 2</button>
<button id="three">Button 3</button>
<button id="four">Button 4</button>
<button id="five">Button 5</button>
<button id="six">Button 6</button>
<button id="seven">Button 7</button>
<button id="eight">Button 8</button>
<button id="nine">Button 9</button>

<script type="text/javascript">
    function alert_three(){
        alert('three');
    }

    var alert_four = function(){
        alert('four');
    }

    function alert_five(){
        alert('five');
    }

    var alert_five = alert_five();
    //this will alert five right away, because we call to the function alert five, which does not return anything but creates an alert box.

    var alert_six = function alert_six(){
        alert('six');
    }

    $('#one').click( function(){
        alert('one');
    });
    //this will work correctly.

    $('#two').click( alert('two') );
    //this will alert two right away, because...?
    //it wont do anything else on click

    $('#three').click( alert_three() );
    //this will alert three right away, because...?
    //it wont do anything else on click

    $('#four').click( alert_four );
    //this will work correctly.

    $('#five').click( alert_five );
    //this wont do anything else on click

    $('#six').click( alert_six );
    //this will work correctly.

    $('#seven').click( function alert_seven(){
        alert('seven');
    });
    //this will work correctly.

    function alert_eight(){
        return function(){
           alert('eight');
        }
    }

    $('#eight').click( alert_eight() );
    //this will work correctly      

    function alert_nine(){
       alert('nine');
    }

    $('#nine').click( alert_nine ); 
    //this will not work
</script>
  • Why will this script alert first five, then two, then three on startup?
  • Why will only buttons 1, 4, 6, and 7 work correcty?
  • How would you describe the differences between the working buttons?
  • Which variation would you use when and why? (meaning: when to give it a name, when to write the function in a variable?)

A Fiddle for the same: http://jsfiddle.net/ZfnaM/5/

هل كانت مفيدة؟

المحلول

Basically I am wondering when it is necessary to use function(){ ... } (without a name) and when to use function function_name(){ ... } (with a name)

It is never really necessary to use either. It is just sometimes more convenient to use one or the other.

and how to execute a function with things like .click() .post() or setTimeout().

If you are using the function that accepts the callback, then you just pass the function you want to use as the callback like any other variable or literal.

If you want to write a function that uses a callback, then it essentially boils down to:

function accepts_callback(callback) {
    callback();
}
function a_callback() {
    alert("This is a callback");
}
accepts_callback(a_callback);

you can't just say .click( function_name() )

Putting () after a function will call it. Don't include them as you can pass it.

Why will this script alert first five,

The first thing you do, other then declare functions, is make a function call: var alert_five = alert_five();

then two

$('#two').click( alert('two') ); //this will alert two right away, because...?

You are calling alert here

//it wont do anything else on click

The return value of alert will always be undefined, which isn't a function

then three on startup?

$('#three').click( alert_three() ); //this will alert three right away, because...?

You are calling the alert_three function immediately.

//it wont do anything else on click

alert_three has no return statement, so it returns undefined, which isn't a function

Why will only buttons 1, 4, 6, and 7 work correcty?

The are the only ones for which you give a function as the argument to click().

نصائح أخرى

What your questions pertain to are called anonymous functions and named functions. For instance, alert_three is a named function while alert_four (even though you've assigned it to a variable) is an anonymous function. These functions are interchangeable and the use of one or the other probably won't matter to you until you start doing things like recursion, where you can call a function within itself (and thus it must be named).

In the jQuery examples, the functions are actually callbacks and within the jQuery methods, they are supposed to follow the arguments, which you have replaced several times with direct function calls. Callbacks give you the ability to act upon the context of the function, usually referred to as this.

When you are using jQuery's .click() you are binding an event handler -- that is the missing vocabulary you seek.

In binding an event handler, you need to pass a function for it work as you are intending. For the items that are alerting right away on page load (five, two and three), that is because you aren't providing a function, just a statement or something that evaluates to a statement instead of a function, so it executes right away and doesn't bind a function definition (which is why when you click the button after page load for those you don't get another alert).

This is what two, three and five have in common -- they aren't (or don't equate to) function definitions, just statements, so they execute when jQuery evaluates the statements on loading the page as it is attempting to add the appropriate functions as event handlers. This includes five, as you are calling a defined function, rather than passing the function definition. You can see in the jQuery documentation for click that you need you pass in a function definition.

This explains the first three questions you were trying to understand.

In regard to the last item, that one is more of an opinion. I'd use a variable for function definitions that I'd want to bind to multiple events to improve maintenance.

Happy scripting!

Clicking alert_five will not work since you have overwritten the function with a variable.

notice that:

 function alert_five(){
            alert('five');
    }
console.log(alert_five)  
//prints
function alert_five(){
        alert('five');
    }

You then assign alert_five to something else, the returned value of return_five() the function and since it doesn't return anything it is undefined.

var alert_five = alert_five();
console.log(alert_five)  
    //prints
undefined

Between bracktes you pass value so when you call function .click(function_name()) you call the function and pass the value that is returned by it.

Some functions take other function as parameter so you have to pass them as function_name

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top