Last active
December 15, 2015 07:39
-
-
Save rwaldron/5225237 to your computer and use it in GitHub Desktop.
Simple Event Emitter class that uses a Symbol for event binding storage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// In Chrome Canary, with Experimental JavaScript enabled... | |
(function( exports ) { | |
// Create a reusable symbol for storing | |
// Emitter instance events | |
var sym = new Symbol(); | |
function Emitter() { | |
this[ sym ] = { | |
events: {} | |
}; | |
} | |
Emitter.prototype.on = function( type, handler ) { | |
var events = this[ sym ].events; | |
if ( !events[ type ] ) { | |
events[ type ] = []; | |
} | |
events[ type ].push( handler ); | |
return this; | |
}; | |
Emitter.prototype.off = function( type, handler ) { | |
var events = this[ sym ].events[ type ]; | |
if ( events ) { | |
if ( !handler ) { | |
events.length = 0; | |
} else { | |
events.splice( events.indexOf(handler), 1 ); | |
} | |
} | |
return this; | |
} | |
Emitter.prototype.emit = function( type, data ) { | |
var event, events; | |
events = (this[ sym ].events[ type ] || []).slice(); | |
if ( events.length ) { | |
while ( event = events.shift() ) { | |
event.call( this, data ); | |
} | |
} | |
return this; | |
} | |
exports.Emitter = Emitter; | |
}(this)); | |
function Serial( path ) { | |
this.path = path; | |
} | |
function Device( path ) { | |
Emitter.call( this ); | |
this.serial = new Serial( path ); | |
} | |
Device.prototype = Object.create( Emitter.prototype ); | |
function handler( data ) { | |
console.log( "signal", data ); | |
} | |
var device = new Device(); | |
device.on( "signal", handler ); | |
device.on( "signal", function() { console.log( 1 ); }); | |
device.on( "signal", function() { console.log( 2 ); }); | |
device.on( "signal", function() { console.log( 3 ); }); | |
// Will trigger 4 events. | |
device.emit( "signal", { a: "alpha", b: "beta" }); | |
device.off( "signal", handler ); | |
// Will trigger 3 events. | |
device.emit( "signal", { a: "alpha", b: "beta" }); | |
console.log( device ); | |
// Device { | |
// serial: Serial { path: ... }, | |
// on: function, | |
// off: function, | |
// emit: function | |
// } | |
// Note that the "device" instance does not have any data | |
// properties that were inherited by Emitter--only the inherited | |
// API from Emitter.prototype and it's own properties |
Would you mind posting a link to the Symbol spec? My Google skills failed me.
@ashmind If it's behind the harmony flag, then it's ECMAScript. I don't see it in the latest ES6 draft though.
thoughts? ES5 compatible Symbol (it's a hack!) https://gist.github.com/WebReflection/5238782
@ashmind, @simevidas if its still interesting: http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types-symbol-type
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bonus
events
could be a Map/WeakMap :D