diff --git a/lib/events.js b/lib/events.js index a1837cc1a9107e..15c22214dc1982 100644 --- a/lib/events.js +++ b/lib/events.js @@ -342,7 +342,7 @@ EventEmitter.init = function(opts) { if (this._events === undefined || this._events === ObjectGetPrototypeOf(this)._events) { - this._events = { __proto__: null }; + this._reset(); this._eventsCount = 0; } @@ -359,6 +359,10 @@ EventEmitter.init = function(opts) { } }; +EventEmitter.prototype._reset = function () { + this._events = { __proto__: null }; +} + function addCatch(that, promise, type, args) { if (!that[kCapture]) { return; @@ -549,7 +553,8 @@ function _addListener(target, type, listener, prepend) { events = target._events; if (events === undefined) { - events = target._events = { __proto__: null }; + target._reset(); + events = target._events; target._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before @@ -687,7 +692,7 @@ EventEmitter.prototype.removeListener = if (list === listener || list.listener === listener) { if (--this._eventsCount === 0) - this._events = { __proto__: null }; + this._reset(); else { delete events[type]; if (events.removeListener) @@ -742,11 +747,11 @@ EventEmitter.prototype.removeAllListeners = // Not listening for removeListener, no need to emit if (events.removeListener === undefined) { if (arguments.length === 0) { - this._events = { __proto__: null }; + this._reset(); this._eventsCount = 0; } else if (events[type] !== undefined) { if (--this._eventsCount === 0) - this._events = { __proto__: null }; + this._reset(); else delete events[type]; } @@ -760,7 +765,7 @@ EventEmitter.prototype.removeAllListeners = this.removeAllListeners(key); } this.removeAllListeners('removeListener'); - this._events = { __proto__: null }; + this._reset(); this._eventsCount = 0; return this; } diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js index cfb49f2c7c7273..2e4e5efdad4c7c 100644 --- a/lib/internal/streams/destroy.js +++ b/lib/internal/streams/destroy.js @@ -332,6 +332,8 @@ function destroyer(stream, err) { } module.exports = { + kConstruct, + kDestroy, construct, destroyer, destroy, diff --git a/lib/internal/streams/duplex.js b/lib/internal/streams/duplex.js index 2b3fe64df9e03a..85a76e5820b22d 100644 --- a/lib/internal/streams/duplex.js +++ b/lib/internal/streams/duplex.js @@ -63,21 +63,6 @@ function Duplex(options) { if (!(this instanceof Duplex)) return new Duplex(options); - this._events = { - close: undefined, - error: undefined, - prefinish: undefined, - finish: undefined, - drain: undefined, - data: undefined, - end: undefined, - pause: undefined, - resume: undefined, - readable: undefined, - pipe: undefined, - unpipe: undefined, - }; - this._readableState = new Readable.ReadableState(options, this, true); this._writableState = new Writable.WritableState(options, this, true); @@ -131,6 +116,25 @@ function Duplex(options) { } } +Duplex.prototype._reset = function () { + this._events = { + close: undefined, + error: undefined, + prefinish: undefined, + finish: undefined, + drain: undefined, + data: undefined, + end: undefined, + pause: undefined, + resume: undefined, + readable: undefined, + pipe: undefined, + unpipe: undefined, + [destroyImpl.kConstruct]: undefined, + [destroyImpl.kDestroy]: undefined, + }; +}; + ObjectDefineProperties(Duplex.prototype, { writable: { __proto__: null, ...ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writable') }, diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js index 83f09194a6358d..2f1c48c47f6d31 100644 --- a/lib/internal/streams/readable.js +++ b/lib/internal/streams/readable.js @@ -316,18 +316,6 @@ function Readable(options) { if (!(this instanceof Readable)) return new Readable(options); - this._events = { - close: undefined, - error: undefined, - data: undefined, - end: undefined, - pause: undefined, - resume: undefined, - readable: undefined, - pipe: undefined, - unpipe: undefined, - }; - this._readableState = new ReadableState(options, this, false); if (options) { @@ -353,6 +341,22 @@ function Readable(options) { } } +Readable.prototype._reset = function () { + this._events = { + close: undefined, + error: undefined, + data: undefined, + end: undefined, + pause: undefined, + resume: undefined, + readable: undefined, + pipe: undefined, + unpipe: undefined, + [destroyImpl.kConstruct]: undefined, + [destroyImpl.kDestroy]: undefined, + }; +}; + Readable.prototype.destroy = destroyImpl.destroy; Readable.prototype._undestroy = destroyImpl.undestroy; Readable.prototype._destroy = function(err, cb) { diff --git a/lib/internal/streams/writable.js b/lib/internal/streams/writable.js index e2a26f36b582c1..74bb7603fdf962 100644 --- a/lib/internal/streams/writable.js +++ b/lib/internal/streams/writable.js @@ -382,14 +382,6 @@ function Writable(options) { if (!(this instanceof Writable)) return new Writable(options); - this._events = { - close: undefined, - error: undefined, - prefinish: undefined, - finish: undefined, - drain: undefined, - }; - this._writableState = new WritableState(options, this, false); if (options) { @@ -431,6 +423,18 @@ ObjectDefineProperty(Writable, SymbolHasInstance, { }, }); +Writable.prototype._reset = function () { + this._events = { + close: undefined, + error: undefined, + prefinish: undefined, + finish: undefined, + drain: undefined, + [destroyImpl.kConstruct]: undefined, + [destroyImpl.kDestroy]: undefined, + }; +}; + // Otherwise people can pipe Writable streams, which is just wrong. Writable.prototype.pipe = function() { errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE());