如何在仍返回值的同时破坏自定义方法链?

时间:2015-02-24 21:33:19

标签: javascript method-chaining

我对搜索变量进行了替换,将已知组转换为组名。

我觉得,在每一步,我都可以进行正则表达式匹配,看看搜索查询中是否还有两个或更多组成员,如果没有,则中止链。这是我经常使用的一个函数,如果没有匹配项,它有责任跳出进程。

我的实际替换链是15长,如果我可以在第一或第二跳出来,这似乎是合适的。

所以,我以为我会写这样的东西

String.prototype.abortreplace = function (m,r) {
    var toreturn;
    if (this.match(/\b\w\b/g).length > 0) {
        toreturn = this.replace(m,r); 
    } else {
        return;
    }
    return toreturn;
}

tx = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p";
tx2 = tx.abortreplace(/a,b,c/g,"first three letters").abortreplace(/d,e,f/g,"second three letters").abortreplace(/g,h,i/g,"third three letters").abortreplace(/j,k,l/g,"fourth three letters").abortreplace(/m,n,o/g,"fifth three letters").abortreplace(/p,q,r/g,"sixth three letters");
alert(tx2);

这适用于这个特定的字符串,因为字符串末尾有p,因为我把它绑定到length > 0。实际上,长度为length > 2。在这种情况下,它返回undefined并中断。 我很好奇如何才能返回字符串并仍然打破链。(我也尝试过return false,它返回false而不是undefined)。

String.prototype.abortreplace = function (m,r) {
    var toreturn;
    if (this.match(/\b\w\b/g).length > 2) {
        toreturn = this.replace(m,r); 
    } else {
        return;
    }
    return toreturn;
}

tx = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p";
tx2 = tx.abortreplace(/a,b,c/g,"first three letters").abortreplace(/d,e,f/g,"second three letters").abortreplace(/g,h,i/g,"third three letters").abortreplace(/j,k,l/g,"fourth three letters").abortreplace(/m,n,o/g,"fifth three letters").abortreplace(/p,q,r/g,"sixth three letters");
alert(tx2);

一个明确的解决方法是在条件不匹配时简单return this,但当然不会中断链,它只是否定每个连续步骤。

我也知道我可以大致这样:

var groups = ["a,b,c","d,e,f"]
var gnames = ["first three letters","second three letters"]
function chainreplace(query,step) {
  if (this.match(/\b\w\b/g).length > 0) {
    query = query.replace(groups[step],gnames[step]);
    if (step < groups.length) {
      query = chainreplace(query,step+1);
    }
    return query;
  }
}
chainreplace("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p",1);

但是如果可能的话,我更喜欢链接方法,更容易重用(类似但不完全相同),而不创建更多的对象数组

1 个答案:

答案 0 :(得分:3)

不是将自己的方法放在String原型(ugh)上,而是可以提供自己的数据结构来做你想做的事。

下面的想法是,有一种类型的对象可以执行您想要的处理并返回可链接对象,并且当时间到来时,它可以返回不同的类型,使用相同的接口来短接后续链接调用:

var replacer = (function() {
  function fixedReplacer(str) {
    var r = {
      abortreplace: function() {
        // this abortreplace just returns the object it was called on
        return r;
      },
      toString: function() {
        return str;
      }
    };
    return r;
  }

  function replacer(str) {
    return {
      abortreplace: function(m, r) {
        return (str.match(/\b\w\b/g)||[]).length > 2 
          ? replacer(str.replace(m, r)) 
          : fixedReplacer(str);
      },
      toString: function() {
        return str;
      }
    };
  }
  
  return replacer;
})();

tx = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p";
tx2 = replacer(tx)
  .abortreplace(/a,b,c/g, "first three letters")
  .abortreplace(/d,e,f/g, "second three letters")
  .abortreplace(/g,h,i/g, "third three letters")
  .abortreplace(/j,k,l/g, "fourth three letters")
  .abortreplace(/m,n,o/g, "fifth three letters")
  .abortreplace(/p,q,r/g, "sixth three letters")
  .toString();
console.log(tx2);

当然,这并不会阻止所有15个方法调用的发生(正如Felix和Bergi所指出的那样,没有抛出异常就不可能),但它可以显着减少执行的计算量。