Skip to content

Commit 4f7f8bb

Browse files
trevnorrisisaacs
authored andcommitted
events: _events to object and undefined not null
By making sure the _events is always an object there is one less check that needs to be performed by emit. Use undefined instead of null. typeof checks are a lot faster than isArray. There are a few places where the this._events check cannot be removed because it is possible for the user to call those methods after using utils.extend to create their own EventEmitter, but before it has actually been instantiated.
1 parent b3ea844 commit 4f7f8bb

4 files changed

+20
-18
lines changed

lib/events.js

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

22-
var isArray = Array.isArray;
2322
var domain;
2423

2524
exports.usingDomains = false;
@@ -33,7 +32,7 @@ function EventEmitter() {
3332
this.domain = domain.active;
3433
}
3534
}
36-
this._events = this._events || null;
35+
this._events = this._events || {};
3736
this._maxListeners = this._maxListeners || defaultMaxListeners;
3837
}
3938
exports.EventEmitter = EventEmitter;
@@ -57,8 +56,9 @@ var PROCESS;
5756
EventEmitter.prototype.emit = function(type) {
5857
// If there is no 'error' event listener then throw.
5958
if (type === 'error') {
60-
if (!this._events || !this._events.error ||
61-
(isArray(this._events.error) && !this._events.error.length)) {
59+
if (!this._events.error ||
60+
(typeof this._events.error === 'object' &&
61+
!this._events.error.length)) {
6262
if (this.domain) {
6363
var er = arguments[1];
6464
er.domainEmitter = this;
@@ -77,7 +77,6 @@ EventEmitter.prototype.emit = function(type) {
7777
}
7878
}
7979

80-
if (!this._events) return false;
8180
var handler = this._events[type];
8281
if (!handler) return false;
8382

@@ -111,7 +110,7 @@ EventEmitter.prototype.emit = function(type) {
111110
}
112111
return true;
113112

114-
} else if (isArray(handler)) {
113+
} else if (typeof handler === 'object') {
115114
if (this.domain) {
116115
PROCESS = PROCESS || process;
117116
if (this !== PROCESS) {
@@ -153,7 +152,7 @@ EventEmitter.prototype.addListener = function(type, listener) {
153152
if (!this._events[type]) {
154153
// Optimize the case of one listener. Don't need the extra array object.
155154
this._events[type] = listener;
156-
} else if (isArray(this._events[type])) {
155+
} else if (typeof this._events[type] === 'object') {
157156

158157
// If we've already got an array, just append.
159158
this._events[type].push(listener);
@@ -165,7 +164,7 @@ EventEmitter.prototype.addListener = function(type, listener) {
165164
}
166165

167166
// Check for listener leak
168-
if (isArray(this._events[type]) && !this._events[type].warned) {
167+
if (typeof this._events[type] === 'object' && !this._events[type].warned) {
169168
var m;
170169
m = this._maxListeners;
171170

@@ -219,11 +218,11 @@ EventEmitter.prototype.removeListener = function(type, listener) {
219218

220219
if (list === listener ||
221220
(typeof list.listener === 'function' && list.listener === listener)) {
222-
this._events[type] = null;
221+
this._events[type] = undefined;
223222
if (this._events.removeListener)
224223
this.emit('removeListener', type, listener);
225224

226-
} else if (isArray(list)) {
225+
} else if (typeof list === 'object') {
227226
for (i = 0; i < length; i++) {
228227
if (list[i] === listener ||
229228
(list[i].listener && list[i].listener === listener)) {
@@ -237,7 +236,7 @@ EventEmitter.prototype.removeListener = function(type, listener) {
237236

238237
if (list.length === 1) {
239238
list.length = 0;
240-
this._events[type] = null;
239+
this._events[type] = undefined;
241240
} else {
242241
list.splice(position, 1);
243242
}
@@ -261,9 +260,9 @@ EventEmitter.prototype.removeAllListeners = function(type) {
261260
// not listening for removeListener, no need to emit
262261
if (!this._events.removeListener) {
263262
if (arguments.length === 0)
264-
this._events = null;
263+
this._events = {};
265264
else if (this._events[type])
266-
this._events[type] = null;
265+
this._events[type] = undefined;
267266
return this;
268267
}
269268

@@ -274,7 +273,7 @@ EventEmitter.prototype.removeAllListeners = function(type) {
274273
this.removeAllListeners(key);
275274
}
276275
this.removeAllListeners('removeListener');
277-
this._events = null;
276+
this._events = {};
278277
return this;
279278
}
280279

@@ -287,7 +286,7 @@ EventEmitter.prototype.removeAllListeners = function(type) {
287286
while (listeners.length)
288287
this.removeListener(type, listeners[listeners.length - 1]);
289288
}
290-
this._events[type] = null;
289+
this._events[type] = undefined;
291290

292291
return this;
293292
};

src/node.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,6 +2477,9 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
24772477
3);
24782478
process->Set(String::NewSymbol("_tickInfoBox"), info_box);
24792479

2480+
// pre-set _events object for faster emit checks
2481+
process->Set(String::NewSymbol("_events"), Object::New());
2482+
24802483
return process;
24812484
}
24822485

test/simple/test-event-emitter-listeners-side-effects.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var fl; // foo listeners
3333
fl = e.listeners('foo');
3434
assert(Array.isArray(fl));
3535
assert(fl.length === 0);
36-
assert.equal(e._events, null);
36+
assert.deepEqual(e._events, {});
3737

3838
e.on('foo', assert.fail);
3939
fl = e.listeners('foo');

test/simple/test-event-emitter-set-max-listeners-side-effects.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ var events = require('events');
2525

2626
var e = new events.EventEmitter;
2727

28-
assert.strictEqual(e._events, null);
28+
assert.deepEqual(e._events, {});
2929
e.setMaxListeners(5);
30-
assert.strictEqual(e._events, null);
30+
assert.deepEqual(e._events, {});

0 commit comments

Comments
 (0)