diff --git a/lib/events.js b/lib/events.js index 280ef979ab4..7e19491e9f5 100644 --- a/lib/events.js +++ b/lib/events.js @@ -203,42 +203,47 @@ EventEmitter.prototype.once = function(type, listener) { // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { - if ('function' !== typeof listener) { - throw TypeError('removeListener only takes instances of Function'); - } + var list, position, length, i; - // does not use listeners(), so no side effect of creating _events[type] - if (!this._events || !this._events[type]) return this; + if (typeof type !== 'string') + throw TypeError('type must be a string'); + if (typeof listener !== 'function') + throw TypeError('listener must be a function'); - var list = this._events[type]; + if (!this._events || !this._events[type]) + return this; - if (isArray(list)) { - var position = -1; - for (var i = 0, length = list.length; i < length; i++) { + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (typeof list.listener === 'function' && list.listener === listener)) { + this._events[type] = null; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isArray(list)) { + for (i = 0; i < length; i++) { if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) - { + (list[i].listener && list[i].listener === listener)) { position = i; break; } } - if (position < 0) return this; - list.splice(position, 1); - if (list.length == 0) + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; this._events[type] = null; - - if (this._events.removeListener) { - this.emit('removeListener', type, listener); + } else { + list.splice(position, 1); } - } else if (list === listener || - (list.listener && list.listener === listener)) - { - this._events[type] = null; - if (this._events.removeListener) { + if (this._events.removeListener) this.emit('removeListener', type, listener); - } } return this;