0

I'm using a Set to maintain a bunch of functions where after calling it once, I can remove it from the set. This is my code below:

let onceWrapper = function() {
  let args = arguments;
  Set.delete(eventName, onceWrapper);
  func.apply(this, arguments);
}

Set.add(eventName, onceWrapper.bind(this));

I'm noticing that when I set a breakpoint after the Set.add(eventName, onceWrapper.bind(this)); line, and run a Set.has(onceWrapper) or Set.has(onceWrapper.bind(this)) in the console, it always returns false. Is there a way I could work around this? What is the explanation as to why my function changes? For what it's worth, when I console.log the function in the Set it returns [native code]. Thanks :)

mistahenry
  • 8,554
  • 3
  • 27
  • 38
alwaysnub
  • 7
  • 2

1 Answers1

1

What happens to a function when I do a bind(this)?

Nothing, the original function (the one you call bind on) is completely unaffected by the call. But bind returns a new function (which is not the same as the function you called it on) that, when called, will call the original ensuring that this is set to bind's first argument.

I should note that I have no idea what Set is in your code. It clearly isn't the standard Set, since that doesn't have static add and has methods. If it's an instance of the standard Set, then there are at least two reasons why onceWrapper isn't in it when you check: add only accepts a single argument (which is odd in my view, but never mind). So if Set is an instance of Set, Set.add(eventName, onceWrapper.bind(this)) will add only eventName to it. The other reason is as described above.

Using a normal Set called things, this should help make things more clear:

function onceWrapper() {
    console.log(typeof this);
}

const things = new Set();

const boundOnceWrapper = onceWrapper.bind(this);
things.add(boundOnceWrapper);

// This logs false because each call to `bind` creates a **new** function
things.has(onceWrapper.bind({foo: "bar"}));

// This logs true because we're checking for the same function we added
things.has(boundOnceWrapper);

Note that even when when calling bind with the same this argument, it will create a new function every time. It doesn't memoize and reuse previous copies.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add Set.add accepts one argument ? – Dhananjai Pai Oct 09 '19 at 15:38
  • @DhananjaiPai - Yeah, I have no idea what `Set` is in the OP's code. I assume it isn't [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) since `Set` doesn't have **`static`** `add` or `has` methods. But `Set` would be a really bizarre identifier to choose regardless of what it is. But the `bind` part of the question was clear enough to answer. :-) – T.J. Crowder Oct 09 '19 at 15:40