2013-09-01 2 views
2

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

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 
} 

Но очевидно, что сделать это просто return s 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

Это столь же кратким, как он получает (кроме того, для некоторого пустячный внутри 'функции safeAdd'). –

+0

Можно перейти в «более логичную» с помощью функции «указатель» (не уверен, что javascript называет это), а затем имеет функцию safeAdd(), которая добавляет дополнительную функцию, когда запись добавляется в список. Однако я сомневаюсь, что это будет более кратким. – ash

ответ

2

Вы могли бы вывернуть ее наизнанку с чем-то вроде этого:

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/

+0

Принимается и поддерживается (в основном для метода 'onPancakes')! Удивительный ответ. У меня есть два вопроса, хотя я не так свободно говорю с 'call()' и 'apply()'. # 1: Зачем вам нужна функция return() 'в' safeAdd() '? # 2: Не 'аргументы [0]' ссылаются на 'callback'? –

+0

Мы возвращаем (анонимную) функцию, чтобы мы могли добавить нашу оболочку, делая ее похожей на обратный вызов, вызывающий вызов. 'arguments' представляет аргументы ближайшей соседней функции, которая была бы анонимной функцией return function() {...}' в этом случае, а не 'safeAdd'. 'call' и' apply' - это методы для функций, которые позволяют вам (a) вызывать функцию с помощью любого «этого» вам и (b) «apply» позволяет передавать аргументы, не зная, что на самом деле аргументы, вы просто отправляете массив вместо отдельных аргументов. –

+0

Мм, не уверен, что полностью понимаю: я понимаю причину оболочки в случае «apply», так что «arguments» относится к возвращенной функции. Но в случае 'call', в котором мы уже передаем' e', что произойдет, если мы удалим оператор 'return function()'? –