Anonymous Callback Function Clarification

21,759

Solution 1

In both examples, you are passing an anonymous function as a parameter.

$("#btn_1").click(function() {
  alert("Btn 1 Clicked");
});

jQuery's click method takes a function as its first parameter. So imagine that click's function definition is this:

function click(fn) {
    // fn will contain a reference to any 
    // function passed as the first parameter to click
    // merely calling fn does nothing, because you are just 'calling' 
    // the reference.
    fn;
    // Since what is inside of fn is a function, you can execute it 
    // with the () syntax
    fn();
}
// Now, you have many ways to pass a function as the first parameter to the function

// 1. As an anonymous function:
click(function() {
    console.log("Hi");
});

// 2. As a named function:
click(function hello() {
    console.log("Hi");
});

// 3. As a reference to a function declaration
function hiThere() {
    console.log("Hi");
}
click(hiThere);

// 4. As a variable that holds an anonymous function inside
var howdy = function () {
    console.log("howdy");
};
click(howdy);

Just imagine that functions are like variables, but they have content inside that can be executed with () at the end.

function hi() {
    console.log('bye');
}

hi; // Calls the reference, but does not execute it. This does nothing.
hi.toString(); // Returns the function as a string
hi(); // Executes the code within the function

Whenever you declare a named function, you can do stuff with it according to its name, like you would do with variables. Of course, unlike variables, they hold executable code inside, and not values.

You can't reference an anonymous function, because it's well... anonymous. UNLESS, you hold it inside of something that has a name, like a var.

var iHoldAFunctionInside = function () {
    console.log('Im not so anonymous now');
};
iHoldAFunctionInside(); // Logs "Im not so anonymous now"

And that is why you can pass an anonymous function as a parameter to a function, and it can execute it as a callback. Because the parameter now 'holds' the anonymous function inside of it:

function iExecuteYourCallback(callback) {
    // callback contains the anonymous function passed to it
    // Similar to doing:
    // var callback = function () { };
    callback();
}
iExecuteYourCallback(function() {
    console.log('Im a callback function!');
});

Hope this helps clear things a bit.

Solution 2

In javascript functions are first class members to you can pass a function as an parameter and the called function can accept it as a named argument.

A simple example can be as below

function testme(callback) {
    //here the argument callback refers to the passed function

    //the timer is used just to delay the execution of the callback
    setTimeout(function () {
        //the passed function is called here
        callback();
    }, 1000)
}

testme(function () {
    alert('x')
})

Demo: Fiddle


In your examples, yes the first callback will be executed once the element with id btn_1 is clicked.

Share:
21,759
djfkdjfkd39939
Author by

djfkdjfkd39939

Updated on August 08, 2022

Comments

  • djfkdjfkd39939
    djfkdjfkd39939 almost 2 years

    I'm brushing up on callback functions and came across the following passage from http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/#

    "When we pass a callback function as an argument to another function, we are only passing the function definition. We are not executing the function in the parameter. In other words, we aren’t passing the function with the trailing pair of executing parenthesis () like we do when we are executing a function.

    And since the containing function has the callback function in its parameter as a function definition, it can execute the callback anytime."

    Can someone explain that? Here are two examples they provided.

    ​//The item is a callback function
    $("#btn_1").click(function() {
      alert("Btn 1 Clicked");
    });
    

    Here is another example:

    var friends = ["Mike", "Stacy", "Andy", "Rick"];
    ​
    friends.forEach(function (eachName, index){
    console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick​
    });
    

    "Note that the callback function is not executed immediately. It is “called back” (hence the name) at some specified point inside the containing function’s body. So, even though the first jQuery example looked like this:

    //The anonymous function is not being executed there in the parameter. ​
    ​//The item is a callback function
       $("#btn_1").click(function() {
         alert("Btn 1 Clicked");
       });
    

    the anonymous function will be called later inside the function body. Even without a name, it can still be accessed later via the arguments object by the containing function."

    For the first example with jquery, what are they saying exactly. If the #btn_1 element is clicked, will the anonymous function be executed? I am assuming it will be executed if the button is clicked, but the wording from the passage was confusing?

    Similarly, for the second example, do they not need to call the function that they passed as an argument bc its anonymous?

  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Ok so in this case bc the function is not anonymous, you have to explicitly execute/call the method?
  • Arun P Johny
    Arun P Johny about 9 years
    @djfkdjfkd39939 which is the case bc
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Would you agree with what I said (i.e. am I interpreting this correctly?)...an anonymous callback is excuted without needing to be explicitly called/called back, while a named function that's an argument to another function needs to be explicitly called / called back?
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Can you explain that - "which is the case bc"...is that a typo?
  • Arun P Johny
    Arun P Johny about 9 years
    @djfkdjfkd39939 an callback method will not get called without an explicit invocation.. but that invocation will be handled by the function to which the callback was passed.... look at the example given above... the callback method is only called by testme to which it was passed
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Is this correct: If its an anonymous callback function, the containing function will automatically handle invoking the callback?
  • Arun P Johny
    Arun P Johny about 9 years
    @djfkdjfkd39939 I don't know what you meant by containing function... do you mean testme in my example... if so yes... a better way will be the function to which the callback was passed
  • Felix Kling
    Felix Kling about 9 years
    @djfkdjfkd39939: Every function, whether it is anonymous or not has to be called in the same way. The only difference between an anonymous function and a named function is that one has a name and the other doesn't. That's it.
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Ok so in the bottom of your example with testme(function()){alert('x')})...if you had previously defined callbackFunction = function(){alert('x')} and then wrote testme(callbackFunction), would you need to include in the body an explicit invocation? i.e. "callbackFunction()" ?
  • Felix Kling
    Felix Kling about 9 years
    @djfkdjfkd39939 The function is called with callback(), whether it is anonymous or not. The function that receives the callback does not care at all whether the function is anonymous or not. FYI, callbackFunction = function(){alert('x')} still creates an anonymous function, you just assigned it to a variable.
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    What I'm asking is ...if the callback method is NOT anonymous (say its called callbackFunc), do you need to include "callbackFunc( )" for it to be executed/ called back?
  • Felix Kling
    Felix Kling about 9 years
    @djfkdjfkd39939: I can only repeat what I said: The callback is always called by testme via callback(). Whether the function is anonymous or not does not matter. I.e. whether you have testme(function() { ... }) or testme(someFunction), doesn't make a difference.
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Ok, so callback( ) is necessary?
  • Arun P Johny
    Arun P Johny about 9 years
    @djfkdjfkd39939 jsfiddle.net/arunpjohny/5q025v8p/2 - its doesn't matter whether it is a named or anonymous - inside the testme function callback refers to whichever function reference was passed so it has to be invoked if the callback need to be executed
  • Felix Kling
    Felix Kling about 9 years
    @djfkdjfkd39939: Of course. callback() calls the function. It's really not as complicated as you seem to think it is. callback is a function. You call a function by adding () after it.
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Ok, and for the first example I wrote w jquery, is that anonymous callback automatically executed? Nowhere is that being called explicitly
  • Arun P Johny
    Arun P Johny about 9 years
    @djfkdjfkd39939 yes... as I said in the example... when the button is clicked
  • Felix Kling
    Felix Kling about 9 years
    @djfkdjfkd39939: It is executed when someone clicks the element. "Nowhere is that being called explicitly" Well, the actual call happens in somewhere internally in the browser. Theoretically. In reality, jQuery might call it. You can look at its source code.
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Ok so for anonymous functions (not just w jquery)- since they're not named and can't be explicitly invoked - if it is used as a callback, you don't need to /couldn't if you wanted to explicitly invoke it?
  • Felix Kling
    Felix Kling about 9 years
    @djfkdjfkd39939: Again, callbacks have nothing to do with anonymous or named functions. var foo = function() {}; is an anonymous function. I can call it with foo(). testme(function() { ... }) is an anonymous function and tesme can execute it via callback(). As long as you have a reference to the function, you can call it. Whether the function has a name or not does not matter. If you mean that you are not able to executed the function outside of testme if you directly pass it via testme(function() { ... }), then yes you are right. Because you don't have a reference to it.
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    So for the last example...if you did not include callback( ) in the body of iExecuteYourCallback, the bottom iExecuteYourCallback(function () {console.log...)}) would not execute?
  • Felix Kling
    Felix Kling about 9 years
    That's a very nice summary (I can't type anymore apparently).
  • Felix Kling
    Felix Kling about 9 years
    @djfkdjfkd39939: iExecuteYourCallback would execute, but the function you are passing to it would not be.
  • Admin
    Admin about 9 years
    Yeah, exactly. The iExecuteYourCallback function would do nothing. It would just be a function that has another function passed to it, but does nothing with it, and dies as quickly as it was typed. Calling the callback is what calls the callback (callback()). @FelixKling Haha, thanks a pretty very much. (Oh, I thought it was intentional :p. Thanks!)
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Ok and last question as this was really helpful....if you did not include "callback ( )" in the body of iExecuteYourCallback, what happens to the anonymous function your passing at the very bottom? It just does nothing, doesn't execute/is just useless even though there is a console.log statement in it?
  • Admin
    Admin about 9 years
    Hmm, well, it gets passed to the function, and the function has it as an argument. But nothing happens with that callback until you explicitly execute it with callback(). The function 'dies' very quickly, and nothing of importance is achieved within its very short lifespan.
  • djfkdjfkd39939
    djfkdjfkd39939 about 9 years
    Right so it wouldn't execute the console.log?
  • Admin
    Admin about 9 years
    Exactly. It doesn't get executed, since you're just passing it as a parameter, but the function does nothing with that parameter you passed to it.
  • Felix Kling
    Felix Kling about 9 years
    @djfkdjfkd39939: It's basically the same as if you declared a function as function foo() { console.log('foo'); }, but never call foo(). The function exists for some time, but it doesn't do anything.