shredding
shredding

Reputation: 5591

Remove and add elements to functions argument list in javascript

I have written an observer in javascript. You can trigger Events like this:

ClassThatExtendsEvent.triggerEvent('EventName', arg1, arg2, ..., argn)

There is a variable number of arguments, with the first argument being the event name. I do as well have subscribers, that are saved in a private property of my event class. They are getting called like this:

Event.prototype.triggerEvent = function() {

  var callbacks = this._events[eventName];      
  if(callbacks !== undefined) {
    for (var i = 0, l = callbacks.length; i < l; i++) {

      // I do not need the first argument here!!!
      callbacks[i].apply(callbacks[i], arguments);
    }
  }
}

However, the subscribers do know the event name, hence it could be ommitted. But I do not know, how to remove one argument from the list (as it's not an array but seems to be some kind of object).

I also need to readd the event name, once it's been deleted, because after notfiying the direct subscribers, a global event system kicks in. This global event system needs the name.

Hence the entire function looks like this:

Event.prototype.triggerEvent = function() {

  // First we deliver to direct subscribers
  var callbacks = this._events[eventName];      
  if(callbacks !== undefined) {
    for (var i = 0, l = callbacks.length; i < l; i++) {
      // I do NOT need the first argument here!!!
      callbacks[i].apply(callbacks[i], arguments);
    }
  }

  // Now we broadcast the event to the entire system

  // I DO need the first argument here!!!

  Facade.getInstance().broadcastEvent.apply(Facade.getInstance(), arguments);      

}

How would you implement this?

Upvotes: 4

Views: 6599

Answers (3)

casablanca
casablanca

Reputation: 70701

Just create a new array with the first argument removed:

var newArgs = [];
for (var i = 1; i < arguments.length; i++) {
  newArgs.push(arguments[i]);
}

and pass the new array to apply:

callbacks[i].apply(callbacks[i], newArgs);

Upvotes: 2

do0g
do0g

Reputation: 311

Mohamed-Ted is correct, but if you do not require the first argument you can inline the manipulation of the arguments using Array.splice as follows:

callbacks[i].apply(callbacks[i], [].splice.call(arguments, 1));

where 1 indicates the position in the arguments list that you want to retain the arguments from.

Upvotes: 2

TedMeftah
TedMeftah

Reputation: 1915

you can "Borrow" the shift method from the Array() object like this:

cache the shift method

shift = [].shift;

then use it to take off the first element of the arguments (since it's just an array like object)

var firstArg = shift.apply(arguments); //in case you need it
.
.
.
callbacks[i].apply(callbacks[i], arguments);

and as @casablanca said,

Many methods will work with anything that behaves like an array (numeric indices and a length property)

the shift method is just one of them.

Upvotes: 12

Related Questions