From 601ee1fd7d313c4acfd1f1d369c15376fcc51707 Mon Sep 17 00:00:00 2001 From: himself65 Date: Fri, 26 Apr 2019 13:10:24 +0800 Subject: [PATCH] lib: bind functions on EventEmitter --- lib/events.js | 19 ++++++++ ...test-event-emitter-check-bind-functions.js | 43 +++++++++++++++++++ .../test-event-emitter-method-names.js | 4 +- 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-event-emitter-check-bind-functions.js diff --git a/lib/events.js b/lib/events.js index 3deb155479187f..346ff7cda5bfba 100644 --- a/lib/events.js +++ b/lib/events.js @@ -266,6 +266,9 @@ function _addListener(target, type, listener, prepend) { return target; } +bindEventEmitterFunction('addListener', '_addListener'); +bindEventEmitterFunction('on', '_addListener'); + EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; @@ -308,6 +311,9 @@ EventEmitter.prototype.prependOnceListener = return this; }; +bindEventEmitterFunction('removeListener', '_removeListener'); +bindEventEmitterFunction('off', '_removeListener'); + // Emits a 'removeListener' event if and only if the listener was removed. EventEmitter.prototype.removeListener = function removeListener(type, listener) { @@ -508,3 +514,16 @@ function once(emitter, name) { emitter.once(name, eventListener); }); } + +function bindEventEmitterFunction(name, target) { + Object.defineProperty(EventEmitter.prototype, name, { + configurable: true, + enumerable: true, + set: function(newVal) { + this[target] = newVal; + }, + get: function() { + return this[target]; + } + }); +} diff --git a/test/parallel/test-event-emitter-check-bind-functions.js b/test/parallel/test-event-emitter-check-bind-functions.js new file mode 100644 index 00000000000000..ee4a40d7ae8d49 --- /dev/null +++ b/test/parallel/test-event-emitter-check-bind-functions.js @@ -0,0 +1,43 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const events = require('events'); + +{ + const E = events.EventEmitter.prototype; + + assert.strictEqual(E.on, E.addListener); + assert.strictEqual(E.off, E.removeListener); + + E.on = function() {}; + assert.strictEqual(E.on, E.addListener); + + E.addListener = function() {}; + assert.strictEqual(E.on, E.addListener); + + E.off = function() {}; + assert.strictEqual(E.off, E.removeListener); + + E.removeListener = function() {}; + assert.strictEqual(E.off, E.removeListener); +} + +{ + const EventEmitter = events.EventEmitter; + + const ee = new EventEmitter(); + + assert.strictEqual(ee.on, ee.addListener); + + ee.on = function() {}; + assert.strictEqual(ee.on, ee.addListener); + + ee.addListener = function() {}; + assert.strictEqual(ee.on, ee.addListener); + + ee.off = function() {}; + assert.strictEqual(ee.off, ee.removeListener); + + ee.removeListener = function() {}; + assert.strictEqual(ee.off, ee.removeListener); +} diff --git a/test/parallel/test-event-emitter-method-names.js b/test/parallel/test-event-emitter-method-names.js index 684024d0276261..eff4e68c1d48a4 100644 --- a/test/parallel/test-event-emitter-method-names.js +++ b/test/parallel/test-event-emitter-method-names.js @@ -29,7 +29,9 @@ assert.strictEqual(E.constructor.name, 'EventEmitter'); assert.strictEqual(E.on, E.addListener); // Same method. assert.strictEqual(E.off, E.removeListener); // Same method. Object.getOwnPropertyNames(E).forEach(function(name) { - if (name === 'constructor' || name === 'on' || name === 'off') return; + if (name === 'constructor' || name === 'on' || name === 'off' || + name === '_addListener' || name === '_removeListener') + return; if (typeof E[name] !== 'function') return; assert.strictEqual(E[name].name, name); });