4

I have an event, and I want to add additional parameters to the named function. I tried following two things:

myDiv.addEventListener('click', evt.call(this, event, 'hello'));

And

myDiv.addEventListener('click', evt(event, 'hello'));

And the problem with both of them, is they get called right away, and don't get called when you click myDiv, i.e. when it's supposed to get called.

How can I add additional parameters to the named function event?

JSFiddle

console.clear();

var myDiv = document.getElementById('myDiv');

function evt(event, param1) {
  console.log(event + ' and ' + param1)
}

myDiv.addEventListener('click', evt.call(this, event, 'hello'));
#myDiv {
  width: 200px;
  height: 200px;
  background-color: green;
}
<div id="myDiv"></div>

9
  • Are you looking for bind? Commented Sep 6, 2016 at 17:18
  • Read about Function#bind Commented Sep 6, 2016 at 17:18
  • @MikeC No, I'm not looking to change this. I just want to add more parameters to the event function Commented Sep 6, 2016 at 17:20
  • 1
    @MikeC You're correct! I thought bind was to just add the this. Thanks! Which is better, performance wise, between using an anonymous wrapper then return evt.call(this, event, 'hello');, or creating a variable with bind? Commented Sep 6, 2016 at 17:34
  • 1
    @Jessica You'd have to check to be sure but my assumption is that an anonymous function is faster since it doesn't have to bind this. It just depends on if you need this to be equal to something and if this is a performance critical section of code. Commented Sep 6, 2016 at 18:57

2 Answers 2

3

You can use an anonymous wrapper:

myDiv.addEventListener('click', function(event) {
    return evt.call(this, event, 'hello');
});

Alternately, you can give yourself a utility function (I tend to call it curry; purist may argue with that name). Here's an unoptimized off-the-cuff:

Object.defineProperty(Function.prototype, "curry", {
    value: function() {
        var f = this;
        var boundArgs = Array.prototype.slice.call(arguments);
        return function() {
            return f.apply(this, boundArgs.concat(Array.prototype.slice.call(arguments)));
        };
    }
});

Then:

myDiv.addEventListener('click', evt.curry('hello'));

But you have to change the order of arguments in evt for that:

function evt(param1, event) {
  console.log(event + ' and ' + param1)
}

...since my version of curry passes it the curried arguments first, then the arguments that the curried version was called with. Although I suppose it's easy enough to swap them around if you prefer.

Here's that curry function in ES2015+:

Object.defineProperty(Function.prototype, "curry", {
    value(...boundArgs) {
        var f = this;
        return function(...callArgs) {
            return f.call(this, ...boundArgs, ...callArgs);
        };
    }
});
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks! Which is better, performance wise, between using an anonymous wrapper then return evt.call(this, event, 'hello');, or creating a variable with bind?
This is rather a meta comment, but: There's a ton of dups, but they are mostly hidden behind poor/irrelevant title and wording. Usually askers don't even know what is their actual problem. Jessica's post has a good title, maybe this post is a potential canonical dup target?
@Teemu: That's exactly what I found when I went looking, the actual problem hidden in onxyz attributes or jQuery or other really bad code. Jessica's is a nice, clear, simple one. I'm in, I'll save this link and use it for this in the future. I've made the answer a CW (just makes me feel better about pointing future ones at it).
@Jessica: It's really, really unlikely to matter which performs better. If I had to guess (and it would be a guess), I'd say probably the anonymous function. But there are lots of side-effects there, such as the fact that because it's a closure, it closes over everything that's in scope when you create it. Modern engines are very good at optimizing that these days, but still... That said, if you keep your functions small and avoid nesting deeply, I doubt it matters.
@T.J.Crowder Thanks!
0

Just use an anonymous function for your event handler, that calls your evt function and passes in the event object and a parameter:

myDiv.addEventListener('click', function ( e ) {
  evt( e, 'hello' );
} );

3 Comments

Will this-context be persistent ?
Not with the above, no.
@Rayon No, but this isn't used in evt. If it were you could use evt.call( this, e, 'hello' );.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.