| Index: lib/events.js | 
| =================================================================== | 
| --- a/lib/events.js | 
| +++ b/lib/events.js | 
| @@ -30,37 +30,46 @@ | 
| /** | 
| * Adds a listener for the specified event name. | 
| * | 
| * @param {string} name | 
| * @param {function} listener | 
| */ | 
| on(name, listener) | 
| { | 
| - let listeners = this._listeners.get(name); | 
| + let listeners = this._listeners.size > 0 ? this._listeners.get(name) : null; | 
| 
 
hub
2019/01/09 22:42:40
I don't see how this is faster (since it is part o
 
Manish Jethani
2019/01/09 23:09:45
This is not about null vs. undefined, this is abou
 
Manish Jethani
2019/01/09 23:11:55
Having said this, the "optimize all methods" part
 
Manish Jethani
2019/01/10 03:50:13
Alright, so I wrote this test:
  // test.js
  let
 
 | 
| if (listeners) | 
| listeners.push(listener); | 
| else | 
| this._listeners.set(name, [listener]); | 
| } | 
| /** | 
| * Removes a listener for the specified event name. | 
| * | 
| * @param {string} name | 
| * @param {function} listener | 
| */ | 
| off(name, listener) | 
| { | 
| - let listeners = this._listeners.get(name); | 
| + let listeners = this._listeners.size > 0 ? this._listeners.get(name) : null; | 
| if (listeners) | 
| { | 
| - let idx = listeners.indexOf(listener); | 
| - if (idx != -1) | 
| - listeners.splice(idx, 1); | 
| + if (listeners.length > 1) | 
| + { | 
| + let idx = listeners.indexOf(listener); | 
| + if (idx != -1) | 
| + listeners.splice(idx, 1); | 
| + } | 
| + else if (listeners[0] === listener) | 
| + { | 
| + // We must use strict equality above for compatibility with | 
| + // Array.prototype.indexOf | 
| + this._listeners.delete(name); | 
| + } | 
| } | 
| } | 
| /** | 
| * Adds a one time listener and returns a promise that | 
| * is resolved the next time the specified event is emitted. | 
| * | 
| * @param {string} name | 
| @@ -83,27 +92,43 @@ | 
| /** | 
| * Returns a copy of the array of listeners for the specified event. | 
| * | 
| * @param {string} name | 
| * @returns {Array.<function>} | 
| */ | 
| listeners(name) | 
| { | 
| - let listeners = this._listeners.get(name); | 
| + let listeners = this._listeners.size > 0 ? this._listeners.get(name) : null; | 
| return listeners ? listeners.slice() : []; | 
| } | 
| /** | 
| + * Checks whether there are any listeners for the specified event. | 
| + * | 
| + * @param {string} [name] The name of the event. If omitted, checks whether | 
| + * there are any listeners for any event. | 
| + * @returns {boolean} | 
| + */ | 
| + hasListeners(name) | 
| + { | 
| + return this._listeners.size > 0 && | 
| + (typeof name == "undefined" || this._listeners.has(name)); | 
| + } | 
| + | 
| + /** | 
| * Calls all previously added listeners for the given event name. | 
| * | 
| * @param {string} name | 
| * @param {...*} [args] | 
| */ | 
| emit(name, ...args) | 
| { | 
| - let listeners = this.listeners(name); | 
| - for (let listener of listeners) | 
| - listener(...args); | 
| + let listeners = this._listeners.size > 0 ? this._listeners.get(name) : null; | 
| + if (listeners) | 
| + { | 
| + for (let listener of listeners.slice()) | 
| + listener(...args); | 
| + } | 
| } | 
| } | 
| exports.EventEmitter = EventEmitter; |