Question

I have a simple scenario in which I check if something exists before adding it, if it does, I return the function (hence exiting). I use this pattern many times and I would like to decouple it in another simple function.

function onEvent(e){
     if( this.has(e) )
          return
     this.add(e);
     // More logic different on an event-basis
}

I would like to decouple it like so:

function safeAdd(e){
     if( this.has(e) )
           return
     this.add(e);
}

function onEvent(e){
     safeAdd(e);
     // More logic
}

But obviously doing so just returns safeAdd and doesn't exit from onEvent, and the rest of the logic gets executed anyways.

I know I could do something like:

function safeAdd(e){
     if( this.has(e) )
           return false
     this.add(e);
     return true
}

function onEvent(e){
     if( !safeAdd(e) )
         return
     // More logic
}

But, since I repeat this a lot, I would like to be as concise as possible.

Was it helpful?

Solution

You could turn it inside out with something like this:

function safeAdd(callback) {
    return function(e) {
        if(this.has(e))
            return false;
        this.add(e);
        return callback.call(this, e);
    };
}

and then you could do things like this:

var obj = {
    onEvent: safeAdd(function(e) {
        console.log('more logic', e);
    }),
    onPancakes: safeAdd(function(e) {
        console.log('pancakes', e);
    }),
    has: function(e) { /* ... */ },
    add: function(e) { /* ... */ }
};

Demo: http://jsfiddle.net/ambiguous/T6pBQ/

And if you need to support more arguments in your functions, switch call to apply and use arguments instead of e:

function safeAdd(callback) {
    return function() {
        if(this.has(arguments[0]))
            return false;
        this.add(arguments[0]);
        return callback.apply(this, arguments);
    };
}

Demo: http://jsfiddle.net/ambiguous/3muzg/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top