3

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>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Jessica
  • 9,379
  • 14
  • 65
  • 136
  • Are you looking for [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)? – Mike Cluck Sep 06 '16 at 17:18
  • Read about `Function#bind` – Rayon Sep 06 '16 at 17:18
  • @MikeC No, I'm not looking to change `this`. I just want to add more parameters to the event function – Jessica Sep 06 '16 at 17:20
  • @Rayon I'm not looking to change this. I just want to add more parameters to the event function – Jessica Sep 06 '16 at 17:20
  • @Jessica Right. Read more on `bind`. It lets you do just that. Like `call`, the first argument is the `this` value but the rest of them are the arguments you would be passing to the function. – Mike Cluck Sep 06 '16 at 17:21
  • Or just call this function inside `anonymous-function` – Rayon Sep 06 '16 at 17:22
  • `function(event) {evt.call(this, event, 'hello');}` – Niet the Dark Absol Sep 06 '16 at 17:22
  • 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`? – Jessica Sep 06 '16 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. – Mike Cluck Sep 06 '16 at 18:57

2 Answers2

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);
        };
    }
});
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks! Which is better, performance wise, between using an anonymous wrapper then `return evt.call(this, event, 'hello');`, or creating a variable with `bind`? – Jessica Sep 06 '16 at 17:32
  • 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 Sep 06 '16 at 17:53
  • 1
    @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). – T.J. Crowder Sep 06 '16 at 18:01
  • 1
    @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 Sep 06 '16 at 18:03
  • @T.J.Crowder Thanks! – Jessica Sep 06 '16 at 18:26
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' );
} );
Paul
  • 139,544
  • 27
  • 275
  • 264