11'use strict' ;
22
3+ const EEEvents = require ( 'internal/symbols' ) . EEEvents ;
4+
35var domain ;
46
57function EventEmitter ( ) {
@@ -13,7 +15,7 @@ EventEmitter.EventEmitter = EventEmitter;
1315EventEmitter . usingDomains = false ;
1416
1517EventEmitter . prototype . domain = undefined ;
16- EventEmitter . prototype . _events = undefined ;
18+ EventEmitter . prototype [ EEEvents ] = undefined ;
1719EventEmitter . prototype . _maxListeners = undefined ;
1820
1921// By default EventEmitters will print a warning if more than 10 listeners are
@@ -30,10 +32,9 @@ EventEmitter.init = function() {
3032 }
3133 }
3234
33- if ( ! this . _events || this . _events === Object . getPrototypeOf ( this ) . _events ) {
34- this . _events = { } ;
35- this . _eventsCount = 0 ;
36- }
35+ if ( ! this [ EEEvents ] ||
36+ this [ EEEvents ] === Object . getPrototypeOf ( this ) [ EEEvents ] )
37+ this [ EEEvents ] = new Map ( ) ;
3738
3839 this . _maxListeners = this . _maxListeners || undefined ;
3940} ;
@@ -119,9 +120,9 @@ EventEmitter.prototype.emit = function emit(type) {
119120 var needDomainExit = false ;
120121 var doError = ( type === 'error' ) ;
121122
122- events = this . _events ;
123+ events = this [ EEEvents ] ;
123124 if ( events )
124- doError = ( doError && events . error == null ) ;
125+ doError = ( doError && ! events . has ( ' error' ) ) ;
125126 else if ( ! doError )
126127 return false ;
127128
@@ -148,7 +149,7 @@ EventEmitter.prototype.emit = function emit(type) {
148149 return false ;
149150 }
150151
151- handler = events [ type ] ;
152+ handler = events . get ( type ) ;
152153
153154 if ( ! handler )
154155 return false ;
@@ -196,32 +197,31 @@ EventEmitter.prototype.addListener = function addListener(type, listener) {
196197 if ( typeof listener !== 'function' )
197198 throw new TypeError ( 'listener must be a function' ) ;
198199
199- events = this . _events ;
200+ events = this [ EEEvents ] ;
200201 if ( ! events ) {
201- events = this . _events = { } ;
202- this . _eventsCount = 0 ;
202+ events = this [ EEEvents ] = new Map ( ) ;
203203 } else {
204204 // To avoid recursion in the case that type === "newListener"! Before
205205 // adding it to the listeners, first emit "newListener".
206- if ( events . newListener ) {
206+ if ( events . has ( ' newListener' ) ) {
207207 this . emit ( 'newListener' , type ,
208208 listener . listener ? listener . listener : listener ) ;
209209
210210 // Re-assign `events` because a newListener handler could have caused the
211- // this._events to be assigned to a new object
212- events = this . _events ;
211+ // this[EEEvents] to be assigned to a new object
212+ events = this [ EEEvents ] ;
213213 }
214- existing = events [ type ] ;
214+ existing = events . get ( type ) ;
215215 }
216216
217217 if ( ! existing ) {
218218 // Optimize the case of one listener. Don't need the extra array object.
219- existing = events [ type ] = listener ;
220- ++ this . _eventsCount ;
219+ events . set ( type , listener ) ;
221220 } else {
222221 if ( typeof existing === 'function' ) {
223222 // Adding the second element, need to change to array.
224- existing = events [ type ] = [ existing , listener ] ;
223+ existing = [ existing , listener ] ;
224+ events . set ( type , existing ) ;
225225 } else {
226226 // If we've already got an array, just append.
227227 existing . push ( listener ) ;
@@ -267,30 +267,26 @@ EventEmitter.prototype.once = function once(type, listener) {
267267 return this ;
268268} ;
269269
270- // emits a 'removeListener' event iff the listener was removed
270+ // emits a 'removeListener' event if the listener was removed
271271EventEmitter . prototype . removeListener =
272272 function removeListener ( type , listener ) {
273273 var list , events , position , i ;
274274
275275 if ( typeof listener !== 'function' )
276276 throw new TypeError ( 'listener must be a function' ) ;
277277
278- events = this . _events ;
278+ events = this [ EEEvents ] ;
279279 if ( ! events )
280280 return this ;
281281
282- list = events [ type ] ;
282+ list = events . get ( type ) ;
283283 if ( ! list )
284284 return this ;
285285
286286 if ( list === listener || ( list . listener && list . listener === listener ) ) {
287- if ( -- this . _eventsCount === 0 )
288- this . _events = { } ;
289- else {
290- delete events [ type ] ;
291- if ( events . removeListener )
292- this . emit ( 'removeListener' , type , listener ) ;
293- }
287+ events . delete ( type ) ;
288+ if ( events . has ( 'removeListener' ) )
289+ this . emit ( 'removeListener' , type , listener ) ;
294290 } else if ( typeof list !== 'function' ) {
295291 position = - 1 ;
296292
@@ -307,17 +303,12 @@ EventEmitter.prototype.removeListener =
307303
308304 if ( list . length === 1 ) {
309305 list [ 0 ] = undefined ;
310- if ( -- this . _eventsCount === 0 ) {
311- this . _events = { } ;
312- return this ;
313- } else {
314- delete events [ type ] ;
315- }
306+ events . delete ( type ) ;
316307 } else {
317308 spliceOne ( list , position ) ;
318309 }
319310
320- if ( events . removeListener )
311+ if ( events . has ( ' removeListener' ) )
321312 this . emit ( 'removeListener' , type , listener ) ;
322313 }
323314
@@ -328,39 +319,32 @@ EventEmitter.prototype.removeAllListeners =
328319 function removeAllListeners ( type ) {
329320 var listeners , events ;
330321
331- events = this . _events ;
322+ events = this [ EEEvents ] ;
332323 if ( ! events )
333324 return this ;
334325
335326 // not listening for removeListener, no need to emit
336- if ( ! events . removeListener ) {
327+ if ( ! events . has ( ' removeListener' ) ) {
337328 if ( arguments . length === 0 ) {
338- this . _events = { } ;
339- this . _eventsCount = 0 ;
340- } else if ( events [ type ] ) {
341- if ( -- this . _eventsCount === 0 )
342- this . _events = { } ;
343- else
344- delete events [ type ] ;
329+ events . clear ( ) ;
330+ } else {
331+ events . delete ( type ) ;
345332 }
346333 return this ;
347334 }
348335
349336 // emit removeListener for all listeners on all events
350337 if ( arguments . length === 0 ) {
351- var keys = Object . keys ( events ) ;
352- for ( var i = 0 , key ; i < keys . length ; ++ i ) {
353- key = keys [ i ] ;
338+ for ( var key of events . keys ( ) ) {
354339 if ( key === 'removeListener' ) continue ;
355340 this . removeAllListeners ( key ) ;
356341 }
357342 this . removeAllListeners ( 'removeListener' ) ;
358- this . _events = { } ;
359- this . _eventsCount = 0 ;
343+ events . clear ( ) ;
360344 return this ;
361345 }
362346
363- listeners = events [ type ] ;
347+ listeners = events . get ( type ) ;
364348
365349 if ( typeof listeners === 'function' ) {
366350 this . removeListener ( type , listeners ) ;
@@ -377,12 +361,12 @@ EventEmitter.prototype.removeAllListeners =
377361EventEmitter . prototype . listeners = function listeners ( type ) {
378362 var evlistener ;
379363 var ret ;
380- var events = this . _events ;
364+ var events = this [ EEEvents ] ;
381365
382366 if ( ! events )
383367 ret = [ ] ;
384368 else {
385- evlistener = events [ type ] ;
369+ evlistener = events . get ( type ) ;
386370 if ( ! evlistener )
387371 ret = [ ] ;
388372 else if ( typeof evlistener === 'function' )
@@ -399,10 +383,10 @@ EventEmitter.listenerCount = function(emitter, type) {
399383} ;
400384
401385EventEmitter . prototype . listenerCount = function listenerCount ( type ) {
402- const events = this . _events ;
386+ const events = this [ EEEvents ] ;
403387
404388 if ( events ) {
405- const evlistener = events [ type ] ;
389+ const evlistener = events . get ( type ) ;
406390
407391 if ( typeof evlistener === 'function' ) {
408392 return 1 ;
@@ -414,6 +398,20 @@ EventEmitter.prototype.listenerCount = function listenerCount(type) {
414398 return 0 ;
415399} ;
416400
401+ Object . defineProperty ( EventEmitter . prototype , '_events' , {
402+ get ( ) {
403+ const thisEvents = this [ EEEvents ] ;
404+ if ( ! thisEvents )
405+ return ;
406+
407+ const events = { } ;
408+ for ( var event of thisEvents ) {
409+ events [ event [ 0 ] ] = event [ 1 ] ;
410+ }
411+ return events ;
412+ }
413+ } ) ;
414+
417415// About 1.5x faster than the two-arg version of Array#splice().
418416function spliceOne ( list , index ) {
419417 for ( var i = index , k = i + 1 , n = list . length ; k < n ; i += 1 , k += 1 )
0 commit comments