diff --git a/lib/events.js b/lib/events.js index 589dc4e79ea234..8139fe5a56f9b4 100644 --- a/lib/events.js +++ b/lib/events.js @@ -31,7 +31,7 @@ EventEmitter.init = function() { } if (!this._events || this._events === Object.getPrototypeOf(this)._events) { - this._events = {}; + this._events = Object.create(null); this._eventsCount = 0; } @@ -198,7 +198,7 @@ EventEmitter.prototype.addListener = function addListener(type, listener) { events = this._events; if (!events) { - events = this._events = {}; + events = this._events = Object.create(null); this._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before @@ -285,7 +285,7 @@ EventEmitter.prototype.removeListener = if (list === listener || (list.listener && list.listener === listener)) { if (--this._eventsCount === 0) - this._events = {}; + this._events = Object.create(null); else { delete events[type]; if (events.removeListener) @@ -308,7 +308,7 @@ EventEmitter.prototype.removeListener = if (list.length === 1) { list[0] = undefined; if (--this._eventsCount === 0) { - this._events = {}; + this._events = Object.create(null); return this; } else { delete events[type]; @@ -335,11 +335,11 @@ EventEmitter.prototype.removeAllListeners = // not listening for removeListener, no need to emit if (!events.removeListener) { if (arguments.length === 0) { - this._events = {}; + this._events = Object.create(null); this._eventsCount = 0; } else if (events[type]) { if (--this._eventsCount === 0) - this._events = {}; + this._events = Object.create(null); else delete events[type]; } @@ -355,7 +355,7 @@ EventEmitter.prototype.removeAllListeners = this.removeAllListeners(key); } this.removeAllListeners('removeListener'); - this._events = {}; + this._events = Object.create(null); this._eventsCount = 0; return this; } diff --git a/test/parallel/test-event-emitter-listener-count.js b/test/parallel/test-event-emitter-listener-count.js index c5b75c819d17f9..875c8eeafd4852 100644 --- a/test/parallel/test-event-emitter-listener-count.js +++ b/test/parallel/test-event-emitter-listener-count.js @@ -1,18 +1,34 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const EventEmitter = require('events'); - const emitter = new EventEmitter(); -emitter.on('foo', function() {}); -emitter.on('foo', function() {}); -emitter.on('baz', function() {}); + +function noop() {} + +emitter.on('foo', noop); +emitter.on('foo', noop); +emitter.on('baz', noop); // Allow any type -emitter.on(123, function() {}); +emitter.on(123, noop); assert.strictEqual(EventEmitter.listenerCount(emitter, 'foo'), 2); assert.strictEqual(emitter.listenerCount('foo'), 2); assert.strictEqual(emitter.listenerCount('bar'), 0); assert.strictEqual(emitter.listenerCount('baz'), 1); assert.strictEqual(emitter.listenerCount(123), 1); + +// The inherited properties should not be counted towards the actual +// listeners count +assert.strictEqual(EventEmitter.listenerCount(emitter, 'toString'), 0); + +// when we add a new listener with the name of an inherited property, it should +// accept it +emitter.on('toString', noop); +assert.strictEqual(EventEmitter.listenerCount(emitter, 'toString'), 1); + +// after removing a listener with the name of an inherited property, the count +// should reduce by one +emitter.removeListener('toString', noop); +assert.strictEqual(EventEmitter.listenerCount(emitter, 'toString'), 0); diff --git a/test/parallel/test-event-emitter-listeners-side-effects.js b/test/parallel/test-event-emitter-listeners-side-effects.js index 23076128eddfc1..62905b01155b17 100644 --- a/test/parallel/test-event-emitter-listeners-side-effects.js +++ b/test/parallel/test-event-emitter-listeners-side-effects.js @@ -23,7 +23,7 @@ assert(fl.length === 1); assert(fl[0] === assert.fail); e.listeners('bar'); -assert(!e._events.hasOwnProperty('bar')); +assert(!e._events['bar']); e.on('foo', assert.ok); fl = e.listeners('foo');