Adding listener functions to a JavaScript object

callback, function, javascript, listener

Solution

I think an array to store the listeners would be a cleaner approach. Also, you should use the prototype object, or make the semiprivate properties real private variables.

function Car() {
    this._color = 'red';
    this._callbacks = {setColor:[]};
};
Car.prototype.setColor = function(color) {
    this._color = color;
    console.log(">>> set car color to " + color);
    for (var i=0; i<this._callbacks['setColor'].length; i++)
        this._callbacks['setColor'][i]();
};
Car.prototype.addListener = function(functionName, handler) {
    this._callbacks[functionName].push(handler);
};

Or:

function Car() {
    var color = 'red';
    var callbacks = {};

    this.setColor = function(c) {
        color = c;
        console.log(">>> set car color to " + color);
        for (var i=0; 'setColor' in callbacks && i<callbacks['setColor'].length; i++)
            callbacks['setColor'][i]();
    };
    this.addListener = function(functionName, handler) {
        if (functionName in callbacks)
            callbacks[functionName].push(handler);
        else
            callbacks[functionName] = [handler];
    };
}

Problem

I have the following code which defines a `Car`. Each `Car` has a color, along with a `setColor(color)` function. I want to add listener functions which are called whenever `setColor(color)` is called, and I want to be able to tack these listener functions on whenever I want. Is this a suitable approach? Is there a cleaner way? ``` function Car() { this._color = 'red'; this._callbacks = {}; this.setColor = function(color) { this._color = color; console.log(">>> set car color to " + color); if (this._callbacks['setColor']) { this._callbacks['setColor'](); } }; this.addListener = function(functionName, handler) { if (this._callbacks[functionName]) { var oldCallback = this._callbacks[functionName]; this._callbacks[functionName] = function() { oldCallback(); handler(); } } else { this._callbacks[functionName] = function() { handler(); } } }; } var car = new Car(); car.setColor('blue'); car.addListener('setColor', function() { console.log("This is listener # 1"); }); car.setColor('green'); car.addListener('setColor', function() { console.log("This is listener # 2"); }); car.setColor('orange'); ``` Output: ``` >>> setColor to blue >>> setColor to green This is listener # 1 >>> setColor to orange This is listener # 1 This is listener # 2 ```

Original source

Related problems