SS = { re: { signal: /SIGNAL_(.*)/ ,slot: /SLOT_(.*)/ } ,setup: function(target){ var i, result, name; target._listeners = {}; for(i in target){ if(!target.hasOwnProperty(i)) continue; result = i.match(SS.re.signal); if(result !== null){ // found a signal name = result[1]; console.log('found signal', name); target[name] = name; if(!target._listeners[name]) target._listeners[name] = []; delete target[i]; } result = i.match(SS.re.slot); if(result !== null){ // found a slot name = result[1]; console.log('found slot', name); // remove SLOT_ prefix target[name] = target[i]; delete target[i]; } } // setup helper methods for(i in this){ if(this.hasOwnProperty(i) && i !== 'setup' && i !== 're'){ target[i] = this[i]; } } console.log('target after setup', target); return target; } ,connect: function(signal, slot){ if(typeof slot !== 'function') throw new Error('Slot must be a function'); if(this[signal] !== signal) throw new Error('Signal not found: ' + signal); if(!this._listeners) this._listeners = {}; if(!this._listeners[signal]) this._listeners[signal] = []; this._listeners[signal].push(slot); } ,disconnect: function(){} ,signal: function(sigName){ console.log('told to fire signal: ', arguments); var args = Array.prototype.slice.call(arguments, 1); if(this._listeners[sigName]) for(var i = 0; i < this._listeners[sigName].length; i++){ this._listeners[sigName][i].apply(this, args); } } //,emit: function(sig){} }; (function(exports){ function MyObj(){} MyObj.prototype = { SLOT_refresh: function(data){ console.log('told to refresh', arguments); } // neat, you can describe what the signals do here ,SIGNAL_READY: 'indicates that the obj is ready for battle' ,SIGNAL_DATA: 'the obj has data ready to dispatch' ,SIGNAL_DIE: 'the obj has been killed or will be killed after dispatch' ,doSomethingAsync: function(){ var self = this; setTimeout(function(){ self.signal(self.READY, 'behold! i am data!', 'so am i'); }, 1000); } }; SS.setup(MyObj.prototype); window.MyObj = MyObj; })(window); var my = new MyObj(); var myToo = new MyObj(); my.doSomethingAsync(); my.connect(my.READY, myToo.refresh); console.log(my, MyObj, MyObj.prototype);