2

Lets say I have an array of functions x = [f1,f2,f3,f4] created by my user, this user can also remove them later on in code.

So my question is, how can a user ask to remove f3 for example if he doesn't know its position?

My idea is to have a function called x.remove(f3) and I need to compare the pointers of the argument and my array items, but how can I do it in JS?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Er85
  • 194
  • 1
  • 13
  • User should somehow store the original references to the functions in `x`. Otherways this is not possible, unless you can't use an object instead of the array. – Teemu Aug 10 '15 at 15:50
  • Comparison of function reference works fine in js. Just use `f === g` to see if you have references to the same function. – mrmcgreg Aug 10 '15 at 16:10
  • If you're using this to manage event handlers, you'll need something [more complex](http://jsfiddle.net/16uvpxhb/) than a simple array. – Teemu Aug 10 '15 at 16:12
  • @Teemu: Why so complicated? OP doesn't seem to deal with multiple events (with different names). – Bergi Aug 10 '15 at 16:17
  • @Bergi Well, when reading [OP's comment](http://stackoverflow.com/questions/31923855/recognize-functions-by-pointer-in-javascript/31923966#comment51761030_31923966) to Mouser's anwer, it seems, that there will be multiple events. Though my example can't remove a particular anonymous handler, it could be developed further to do that too. – Teemu Aug 10 '15 at 16:27
  • @Teemu: Hm, OP just has one array per event, and that's what he has problems with. I still think your code is overcomplicated (alone this `Object.create` thing!), and "an event system" doesn't necessarily involve the DOM, which is what most of your code seems to be about. – Bergi Aug 10 '15 at 16:35
  • @Bergi Then I might have misunderstood OP's comment. The only DOM part in the example is involved in the element which has the event handler attached though. The `Object.create()`-stuff is just because the snippet is a very short simplification of an "event system" I'm using. – Teemu Aug 10 '15 at 16:41
  • @Teemu: Hm, for me an "event system" is more like node's `EventEmitter`, with `add`, `remove` and `fire` methods. No element, context, bubble involved… – Bergi Aug 10 '15 at 16:46

3 Answers3

2

This doesn't have anything to do specifically with functions. Functions are objects, and have an identity, so if you have a reference to the function (which the user has) you can find it in the array and remove it from there:

 function remove(arr, val)
     var i = arr.indexOf(val);
     if (i != -1)
          arr.splice(i, 1);
 }

This works for every arbitrary value, not just for functions. In your case, you'd just do remove(x, f3).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

I would change the array into an object:

x = {"f1" : f1, "f2": f2, "f3": f3, "f4" : f4};

That way you can select on name.

delete x['f3'];

This is the basic. I don't know your application, but you should assign an id to the function and attach that id to the delete button. When the user hits the button it will execute the remove function, stripping the function from the object.

Another possibility is when the functions aren't anonymous and have a name: store the name as a string. A function can be called like this to:

var x = ["f1", "f2", "f3", "f4"];
window[x[0]](); //which is window['f1']() = window.f1()
Mouser
  • 13,132
  • 3
  • 28
  • 54
  • thanks for your answer, the purpose is to create kid of an event system, where you can listen to an event and call a function when this event is triggered. I can add several functions per event - this is the array of functions that I keep, and now I try to think how I can unregister a specific function per event but keep the others. in your solution with the objects, the key in the object is the entire string of the function, not sure if its a good practice, and ofcourse I want to support anonnymous functions – Er85 Aug 10 '15 at 16:06
  • Those keys should just be simple strings. – Mouser Aug 10 '15 at 16:28
  • what happens if my function is anonnymous? or event if I have several of those? how can I know the name of it? consider that the user doesn't know what names I give to his functions so he cant ask to remove by a name I gave – Er85 Aug 10 '15 at 17:05
0

Use the equality operator to compare references

var f1 = function() { alert(1) };
var f2 = function() { alert(2) };
var f3 = function() { alert(3) };

var x = [f1, f2, f3];

var remove = window['f2']; //or f2

for (var i = 0; i < x.length; i++) {
  x[i](); // alerts 1..2..3    
  if (x[i] == remove)
    x.splice(i, 1);
}

for (var i = 0; i < x.length; i++) {
    // alerts 1..3
    x[i]();
}
Alex K.
  • 171,639
  • 30
  • 264
  • 288
  • You should either `break;` when you've found the element, so that it's clear that you only remove the first one, or use `i--` so that you don't skip any occurences – Bergi Aug 10 '15 at 16:14