Skip to content

Instantly share code, notes, and snippets.

Forked from domenic/event-emitter.js
Created August 21, 2016 02:22
Show Gist options
  • Save trusktr/d39bcdeb3051017e4ac7fa0e85e73d6c to your computer and use it in GitHub Desktop.
Save trusktr/d39bcdeb3051017e4ac7fa0e85e73d6c to your computer and use it in GitHub Desktop.
Revealing constructor pattern event-emitter
// This event emitter emits events, but reserves the right to publish events to
// for its creator. It uses a WeakMap for true encapsulation.
const eesToEventMaps = new WeakMap();
export default class EventEmitter {
constructor(publisher) {
const eventMap = Object.create(null);
eesToEventMaps.set(this, eventMap);
on(eventName, handler) {
const eventMap = eesToEventMaps.get(this);
let handlers = eventMap[eventName];
if (!handlers) {
handlers = eventMap[eventName] = [];
off(eventName, handler) {
const eventMap = eesToEventMaps.get(this);
const handlers = eventMap[eventName];
if (!handlers) {
const index = handlers.indexOf(handler);
if (index === -1) {
handlers.splice(index, -1);
function makePublish(ee) {
const eventMap = eesToEventMaps.get(ee);
return function (eventName, ...args) {
const handlers = eventMap[eventName];
if (handlers) {
handlers.forEach(h => h(...args));
const myEE = new EventEmitter(publish => {
// Wait for interesting things to happen, then call
// `publish("eventName", ...args)`.
// The other code only gets access to `on` and `off`: it cannot trigger spurious
// events, but only listen for them. This makes it safe to pass `myEE` to
// multiple consumers without worrying about them accidentally stepping on each
// other's toes.
// (Of course, they could intentionally step on each other's toes, e.g. by
// overwriting `on` or `off`. For true security you'll need to deeply-freeze
// `myEE`, and do a few more things, e.g. to protect against plan interference
// attacks. We're not focused on that right now, but instead on the API
// ergonomics.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment