Observer pattern implementation in JavaScript I'm working on redeveloping a running project, and the main goal is to enhance the JS code as much as possible.

I'm using the observer pattern to watch the window events like scroll, and resize

The following is my implementation:

module.exports = {

    // Watch window scrolling/resizing, then fire a set of watchers
    watchWindow: {
        watchers: {
            scroll: {},
            resize: {}
        },
        initialized: false,
        init: function () {
            this.initialized = true;
            var watchers = this.watchers;
            $window.on('scroll resize', function (e) {
                for(var id in watchers[e.type]) {
                    if(watchers[e.type].hasOwnProperty(id)) {
                        if (typeof watchers[e.type][id] === 'function') {
                            watchers[e.type][id](e.type === 'scroll' ? $window.scrollTop() : $window.width());
                        }
                    }
                }
            });
        },
        addWatcher: function (settings) {
            var id = Date.now();
            this.watchers[settings.event][id] = settings.callback;
            !this.initialized &amp;&amp; this.init();
            return id;
        },
        removeWatcher: function(settings) {
            delete this.watchers[settings.event][settings.id];
        }
    }
}


Then that's how I'm using it:

// Watch window resizing
utilities.watchWindow.addWatcher({
    event: 'resize',
    callback: function (windowWidth) {
        mobileMenuEnabled = windowWidth &lt; sideMenuBreakpoint;
    }
});
You could add multiple event handlers for each Watcher instead of initializing a global one.

watchWindow: {
    addWatcher: function (settings) {
        $window.on(settings.event, function (e) {
            settings.callback(e.type === 'scroll' ? $window.scrollTop() : $window.width());
        })
    },
    removeWatcher: function(settings) {
        $window.off(settings.event, settings.callback);
    }
}


In this example you would be using the same settings object to add and remove event handlers, but you could of course keep your map of handlers and generated id's if you prefer.