4

我用javascript写了一个观察者。您可以像这样触发事件:

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

有可变数量的参数,第一个参数是事件名称。我也有订阅者,它们保存在我的事件类的私有属性中。他们被这样称呼:

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);
    }
  }
}

但是,订阅者确实知道事件名称,因此可以省略。但我不知道如何从列表中删除一个参数(因为它不是数组,但似乎是某种对象)。

我还需要读取事件名称,一旦它被删除,因为在通知直接订阅者之后,全局事件系统就会启动。这个全局事件系统需要名称。

因此整个函数看起来像这样:

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);      

}

你将如何实现这一点?

4

3 回答 3

12

您可以像这样从对象中“借用”该shift方法:Array()

缓存shift方法

shift = [].shift;

然后用它去掉第一个元素arguments(因为它只是一个类似对象的数组)

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

正如@casablanca 所说,

许多方法适用于任何行为类似于数组的东西(数字索引和长度属性)

shift方法只是其中之一。

于 2012-11-08T19:52:54.500 回答
2

只需创建一个删除第一个参数的新数组:

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

并将新数组传递给apply

callbacks[i].apply(callbacks[i], newArgs);
于 2012-07-04T10:58:29.930 回答
2

Mohamed-Ted 是正确的,但如果您不需要第一个参数,您可以使用以下方法内联对参数的操作Array.splice

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

where1指示要从中保留参数的参数列表中的位置。

于 2014-02-15T22:08:48.350 回答