简体   繁体   中英

How to pass parameters in function calls by reference in JavaScript?

I have recently asked the question, Why should we use anonymous functions with jQuery instead of the function directly? and along with the accepted answer came a second question: How to pass arguments to one JS function that we are invoking by reference?

How would be the call to $("a").on("click", retornaNada); whether this function receives a simple parameters such as a number or as a more complex object?

To your actual example:

$("a").on("click", retornaNada); 

If you read the jQuery docs , it will tell you what it will pass to the handler. It will call whatever function you provide and pass it an eventObject which has various properties (see the docs). If you want, you can pass more data as part of your binding that will end up in event.data (see the section Passing data to the handler )

So if you do:

$("a").on("click", { foo:"bar" }, retornaNada);

and have a function retornaNada :

function retornaNada(e) {
    console.log(e.data.foo);     // logs "bar"
}

Alternatively, if you want more control over what gets passed to your function, this would be a good place to use those anonymous functions:

$("a").on("click", function() { 
    retornaNada(myOwn, argumentsTo, myFunction); 
});

So, for example, if retornaNada looked like this:

function retornaNada(anumber) {

}

You could then do:

$("a").on("click", function() { 
    retornaNada(1); 
});

Edit : Some thoughts on the first option (using data ) and the second (wrapping with an anonymous function).

Let's say you have a function called addToTotal that is going to increase a counter every time an event happened. With the first option, your function might look like this:

function addToTotal(e) {
    theTotal += e.data.amountToAdd;
}

This is fine, of course, but what if you also have other logic elsewhere that you need to increase your total? You need to either reproduce the logic of the body of your function (either inline or in another function), or you need to "fake" and event object

addToTotal({ data: 1 });     // fake event object - this is kind of stupid

In addition, a function addToTotal that takes an argument that isn't actually the amount you want to add is goofy and will likely confuse anybody else looking at your code.

In that case, it would be a lot better to define addToTotal more sensibly to take a number and add it to the total :

function addToTotal(number) {
    theTotal += number;
}

Now I can call it anywhere:

addToTotal(1);     // this looks a lot better!

but I can't use it as an event handler because it will pass an eventObject instead of the number I need so this:

$("a").on("click", addToTotal)

Isn't going to work. So instead, we can wrap our function in an annoymous function:

$("a").on("click", function() { addToTotal(1); } )

And now we have an event that will call our function, and our function doesn't look goofy and can be completely agnostic about whether it's called from an event handler or called somewhere else.

Of course, if you really wanted to, you could do this:

function addToTotalEventHandler(e) {
    addToTotal(e.data.amountToAdd);
}

And then:

$("a").on("click", { data : 1 }, addToTotalEventHandler);

But that is basically the same as the anonymous wrapper, but you've had to create a new function just for this single use.

When you use $("a").on("click", retornaNada) the given function is called like:

retornaNada.call(<anchor-object>, <event-data>)

Whereby <anchor-object> is the DOM object of the anchor that's clicked, available to your function as this , and <event-data> is a wrapper object for the click event itself, so:

function retornaNada(e)
{
    console.log(this); // DOM object
    console.log(e); // event object
}

If your function does not expect an event object as its first argument, the typical thing to do is use a wrapper function, ie:

$('a').on('click', function(e) {
    retornaNada(... whatever ...);
});

Here is an example:

var foo = function () {
  console.log(arguments);
};

We can invoke it as:

foo(1,2,3,4);                  //[1,2,3,4]
foo.apply(window, [1,2,3,4]);  //[1,2,3,4]
foo.call(window, 1,2,3,4);     //[1,2,3,4]

We can pass foo to another function and invoke it the same way:

function bar() {
  foo(1,2,3,4);                  //[1,2,3,4]
  foo.apply(window, [1,2,3,4]);  //[1,2,3,4]
  foo.call(window, 1,2,3,4);     //[1,2,3,4]
}

You can use the Function Prototype Bind .

Basicly, it rebind the arguments of the function reference. But you lose the reference to this (which is the same of event.currentTarget ).

You would use it like this :

$("a").on("click", retornaNada.bind('something that will equal this', 'arg1', 1));

And the function receive :

function retornaNada(a, b, c){
    console.log(this); //'something that will equal this'
    console.log(a); //'arg1'
    console.log(b); // 1
    console.log(c); // Event object
}

Using bind, the first passed argument will be the this reference and following argument will be arguments in function.

The original arguments (in this case Event ) will always be the last one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM