Javascript возвращающая вмещающую функцию

У меня есть простой сценарий, в котором я проверяю, если что-то существует, прежде чем добавить его, если это так, я return функция (следовательно, выход). Я использую этот шаблон много раз, и я хотел бы отделить его в другой простой функции.

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

Я хотел бы отделить это так:

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

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

Но, очевидно, делает это просто returns safeAdd и не выходит из onEventи остальная часть логики выполняется в любом случае.

Я знаю, что мог бы сделать что-то вроде:

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

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

Но, поскольку я повторяю это много раз, я хотел бы быть как можно более кратким.

1 ответ

Решение

Вы можете вывернуть это наизнанку примерно так:

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

и тогда вы могли бы делать такие вещи:

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) { /* ... */ }
};

Демо: http://jsfiddle.net/ambiguous/T6pBQ/

И если вам нужно поддерживать больше аргументов в ваших функциях, переключитесь call в apply и использовать arguments вместо e:

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

Демо: http://jsfiddle.net/ambiguous/3muzg/

Другие вопросы по тегам