【问题标题】:Javascript return enclosing functionJavascript返回封闭函数
【发布时间】:2013-09-01 05:02:15
【问题描述】:

我有一个简单的场景,我在添加之前检查是否存在某些东西,如果存在,我 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
}

但是,由于我重复了很多次,所以我希望尽可能简洁。

【问题讨论】:

  • 这是最简洁的(除了safeAdd 函数中的一些摆弄)。
  • 可以通过函数“指针”传入“更多逻辑”(不确定 javascript 是否调用它),然后在将条目添加到列表时让 safeAdd() 调用该附加函数.但是,我怀疑这是否更简洁。

标签: javascript refactoring return dry decoupling


【解决方案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/

【讨论】:

  • 接受和赞成(主要用于onPancakes 方法)!惊人的答案。不过,我有两个问题,因为我不太熟悉call()apply()。 #1:为什么你需要safeAdd() 中的return function()? #2:arguments[0]不是指callback吗?
  • 我们返回一个(匿名)函数,这样我们就可以添加我们的包装器,同时让它看起来像 callback 就是被调用的所有东西。 arguments 表示最接近的周围函数的参数,在这种情况下是匿名的 return function() { ... } 函数,而不是 safeAddcallapply 是函数上的方法,允许您 (a) 使用您需要的任何 this 调用函数,并且 (b) apply 允许您传递参数而不必知道参数实际上是什么,您只需发送一个数组而不是单个参数。
  • 嗯,不确定我是否完全理解:我理解apply 情况下包装器的原因,因此arguments 指的是返回的函数。但是在我们已经通过ecall 的情况下,如果我们删除return function() 语句会发生什么?
  • 但是当我们调用safeAdde 是不知道的,e 是在以后调用onEventonPancakes 时知道的。我们运行safeAdd 将构建obj,稍后调用safeAdd 返回的函数。
  • 酷。函数构建函数第一次接触时可能会有点奇怪,但一旦掌握了它,它就会是一种超级有用的技术。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
相关资源
最近更新 更多