diff --git a/lib/events.js b/lib/events.js index 7e19491e9f5..45577c8c602 100644 --- a/lib/events.js +++ b/lib/events.js @@ -19,7 +19,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -var isArray = Array.isArray; var domain; exports.usingDomains = false; @@ -33,7 +32,7 @@ function EventEmitter() { this.domain = domain.active; } } - this._events = this._events || null; + this._events = this._events || {}; this._maxListeners = this._maxListeners || defaultMaxListeners; } exports.EventEmitter = EventEmitter; @@ -57,8 +56,9 @@ var PROCESS; EventEmitter.prototype.emit = function(type) { // If there is no 'error' event listener then throw. if (type === 'error') { - if (!this._events || !this._events.error || - (isArray(this._events.error) && !this._events.error.length)) { + if (!this._events.error || + (typeof this._events.error === 'object' && + !this._events.error.length)) { if (this.domain) { var er = arguments[1]; er.domainEmitter = this; @@ -77,7 +77,6 @@ EventEmitter.prototype.emit = function(type) { } } - if (!this._events) return false; var handler = this._events[type]; if (!handler) return false; @@ -111,7 +110,7 @@ EventEmitter.prototype.emit = function(type) { } return true; - } else if (isArray(handler)) { + } else if (typeof handler === 'object') { if (this.domain) { PROCESS = PROCESS || process; if (this !== PROCESS) { @@ -153,7 +152,7 @@ EventEmitter.prototype.addListener = function(type, listener) { if (!this._events[type]) { // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; - } else if (isArray(this._events[type])) { + } else if (typeof this._events[type] === 'object') { // If we've already got an array, just append. this._events[type].push(listener); @@ -165,7 +164,7 @@ EventEmitter.prototype.addListener = function(type, listener) { } // Check for listener leak - if (isArray(this._events[type]) && !this._events[type].warned) { + if (typeof this._events[type] === 'object' && !this._events[type].warned) { var m; m = this._maxListeners; @@ -219,11 +218,11 @@ EventEmitter.prototype.removeListener = function(type, listener) { if (list === listener || (typeof list.listener === 'function' && list.listener === listener)) { - this._events[type] = null; + this._events[type] = undefined; if (this._events.removeListener) this.emit('removeListener', type, listener); - } else if (isArray(list)) { + } else if (typeof list === 'object') { for (i = 0; i < length; i++) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { @@ -237,7 +236,7 @@ EventEmitter.prototype.removeListener = function(type, listener) { if (list.length === 1) { list.length = 0; - this._events[type] = null; + this._events[type] = undefined; } else { list.splice(position, 1); } @@ -261,9 +260,9 @@ EventEmitter.prototype.removeAllListeners = function(type) { // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) - this._events = null; + this._events = {}; else if (this._events[type]) - this._events[type] = null; + this._events[type] = undefined; return this; } @@ -274,7 +273,7 @@ EventEmitter.prototype.removeAllListeners = function(type) { this.removeAllListeners(key); } this.removeAllListeners('removeListener'); - this._events = null; + this._events = {}; return this; } @@ -287,7 +286,7 @@ EventEmitter.prototype.removeAllListeners = function(type) { while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } - this._events[type] = null; + this._events[type] = undefined; return this; }; diff --git a/src/node.cc b/src/node.cc index 847ebaffb26..25354e9d84d 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2477,6 +2477,9 @@ Handle SetupProcessObject(int argc, char *argv[]) { 3); process->Set(String::NewSymbol("_tickInfoBox"), info_box); + // pre-set _events object for faster emit checks + process->Set(String::NewSymbol("_events"), Object::New()); + return process; } diff --git a/test/simple/test-event-emitter-listeners-side-effects.js b/test/simple/test-event-emitter-listeners-side-effects.js index 92a5bef97c0..c6218e0598a 100644 --- a/test/simple/test-event-emitter-listeners-side-effects.js +++ b/test/simple/test-event-emitter-listeners-side-effects.js @@ -33,7 +33,7 @@ var fl; // foo listeners fl = e.listeners('foo'); assert(Array.isArray(fl)); assert(fl.length === 0); -assert.equal(e._events, null); +assert.deepEqual(e._events, {}); e.on('foo', assert.fail); fl = e.listeners('foo'); diff --git a/test/simple/test-event-emitter-set-max-listeners-side-effects.js b/test/simple/test-event-emitter-set-max-listeners-side-effects.js index a50479784ad..604129796ea 100644 --- a/test/simple/test-event-emitter-set-max-listeners-side-effects.js +++ b/test/simple/test-event-emitter-set-max-listeners-side-effects.js @@ -25,6 +25,6 @@ var events = require('events'); var e = new events.EventEmitter; -assert.strictEqual(e._events, null); +assert.deepEqual(e._events, {}); e.setMaxListeners(5); -assert.strictEqual(e._events, null); +assert.deepEqual(e._events, {});