Function as parameter in functions in jQuery

9

I always used some functions without really understanding what was happening and where these parameters came from. I say the following:

Example 1:

$("#link").on("click", function(event){
   event.preventDefault(); 
});

Example 2:

$.getJSON("http://minhaurl", {id: 20}, function(data){
    $.each(data, function(key, value){
        console.log(value.property)
    })
});

In the first example, where does this event come from? What leaves me in doubt is that no matter the name of this parameter, it will always work. And I did not declare it anywhere!

In the second, in the same way. Where does data come from, which can be changed to any other name as in the first example?

I simply use following examples, but I need to understand how it works.

Can anyone explain me?

    
asked by anonymous 22.01.2015 / 12:27

3 answers

12

Your attitude is commendable would like more programmers to be like this.

These functions are called callback . They are created just to respond with an action to something that the environment where your application is running requires. Data is normally passed to functions. This is a way to pass algorithms to functions. Note that this function you are creating is itself a parameter of a function you are calling. This is how the callback ( in English ) works.

In this case you do not see the calls anywhere because this is done inside the browser or at least inside some library that you are using. You do not see calls because they are not your application's responsibility.

Note that nothing prevents you from creating such a mechanism within your application. There are some advantages to doing this in some situations giving enough flexibility and power to the application. Of course if you create the entire mechanism in your application you will have to create the call to these functions somewhere.

This is an excellent way of communicating parts that are not known, much used to treat in English ), asynchronicity as used in # ( API ( in English ).

So you have to study the API you're using. You have to look for the documentation that explains what it does because it is important and the different ways to use it. Knowing all the information you can be much more creative. This is what sets true developers apart from cake recipe followers.

The documentation has the function signature. That is, there it shows how to declare the function that the API will call. It shows what parameters it should receive and what it should return. Usually describes it gives examples of the minimum that should be done in the body of the function. You can do what and whatever way you want internally, you just need to respect the input and output protocols and do something minimally useful that in some cases may even be nothing.

In some cases it may be exaggerated to use something like this. In the examples I'm using I can not tell if there is any real advantage in using each . In the background it replaces the use of for each to leave the code smaller, as far as I know nothing more than this, at least in this case. Decrease code is fine but is not something without cost , this should not be the main objective. It is often best to use Vanilla JS at least because it is much faster but in this case it is less flexible as well and legibility is questionable.

But this is an easy case to understand:

// args is for internal usage only
each: function( obj, callback, args ) { //note que args não faz parte da API pública
    var i = 0,
        length = obj.length,
        isArray = isArraylike( obj );

    if ( args ) { //aqui trata quando há algo interno acontecendo
        if ( isArray ) {
            for ( ; i < length; i++ ) {
                if ( callback.apply( obj[ i ], args ) === false ) {
                    break;
                }
            }
        } else {
            for ( i in obj ) {
                if ( callback.apply( obj[ i ], args ) === false ) {
                    break;
                }
            }
        }

    // A special, fast, case for the most common use of each
    } else { //tratamento do caso público que é que nos interessa
        if ( isArray ) { //tratamento especial se for um array
            for ( ; i < length; i++ ) { //varrrrá todo array passado
                if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                    break; //encerra quando a chama acima falhar
                }
            }
        } else { //outros objetos
            for ( i in obj ) { //vai analisar cada elemento do objeto passado
                if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
                    break;
                }
            }
        }
    }

    return obj;
},

Font .

This is each of jQuery that you do not know where the call comes from.

Note that whoever does the individual operation is the callback.call function that is part of JavaScript. It is a function that serves just to call other functions that are passed as an argument. Ultimately the call function will be called. It has the necessary infrastructure to perform the actual execution of the desired function.

This has nothing to do with meta-programming. At least not directly.

getJSON documentation.

documentation on .

each documentation.

    
22.01.2015 / 12:46
4

@Maniero's answer was on the fly, I highlight this excerpt:

  

Normally, data is passed to functions. This is a way to pass algorithms to functions. Note that this function you are creating is itself a parameter of a function you are calling. This is how callback works.

     

In this case you do not see the calls anywhere because this is done inside the browser or at least inside some library that you are using. You do not see calls because they are not your application's responsibility.

.on("click", function(event) { })

Your first example assigns a listener to a click event. There you define what will be the callback of an asynchronous operation, an operation that will not occur immediately (but when the user interacts with a click).

When the click occurs, the browser creates a object that represents the event and passes it to the corresponding listener. This object is what you get if you are listening to the event with pure JavaScript:

elemento.addEventListener('click', function(evento) {
    // estou falando deste objeto aqui -------^
});

jQuery will wrap the original object in a custom object, normalized for greater compatibility between browsers, and this is what the function in your code receives.

"no matter the name of this parameter, it will always work"

It's true. Think about it, you are defining a function. Who defines the function is that it names the parameters. In fact you do not even need to create named parameters, if arguments are passed you can still access them in the order via arguments[0] , arguments[1] etc. Who is responsible for calling the function and passing the arguments is first the browser, and then the jQuery that passes this forward to its function.

$.getJSON(url, {}, function(data){ })

The operation is very similar to that of the listener , with the difference that the asynchronous event is not originated by a user action, but by the arrival of the requested response to the server. From then on it's all the same: the browser calls a function and provides the answer (but in this case it is not passed to the function, is available as property of object XMLHttpRequest ). JQuery takes this response, wraps it in a cusomized object , and passes that object to its function.

Deepening

If you want to better understand how your browser handles asynchronous JavaScript operations, then this question and answer might help: #

    
23.01.2015 / 03:25
2

In order to understand the parameters received by the jQuery functions, you need to check the documentation .

For example, in the on function. The simplest way to use it is as follows:

.on( events, handler )

As you already know, the parameter events receives a string with the desired events and handler receives a function to execute when the event is triggered.

In the documentation, jQuery informs that handler will receive the following parameters:

( Event eventObject [, Anything extraParameter ] [, ... ] )

The first parameter will be an object of type Event . The others are optional and not the case.

In short, when one of the parameters is a function (callback), you should look in the documentation to see what parameters it will receive.

Note: Another way to check which parameters your function is receiving is by checking all the arguments the function received.

console.log(arguments);
// a variável arguments é um array contendo
// todos os argumentos recebidos pela função
    
22.01.2015 / 12:45