JavaScript 链式连接函数?

Rob*_*Rob 2 javascript string join concatenation method-chaining

请不要使用 jQuery!

网上说应该避免使用 JS 的原生String.concat()join()函数,因为它们的性能较差,而一个简单的+=赋值的for()循环应该会运行得更快。

所以我尝试用纯 JavaScript 创建一个函数来连接字符串。这在某种程度上是我的设想:

  • 我想要一个主函数concatenate(),它将连接所有传递的参数,并在每个连接的参数之后插入一个变量字符串(最后一个参数除外)。

  • 如果 main 函数是单独调用的,并且没有链式.using()函数,则该变量字符串应该为空字符串,这意味着结果中没有分隔符。

  • 我想要一个链接的子函数.using(),它会告诉主concatenate()函数除了默认的 '' 空字符串之外要在每个连接段之后添加哪些特定字符串。

理论上,它应该像这样工作:

concatenate('a','b','c');              /* result: 'abc'   */
concatenate('a','b','c').using('-');   /* result: 'a-b-c' */
Run Code Online (Sandbox Code Playgroud)

我想避免使用两个单独的函数,例如concatenate()concatenateUsing(),因为concatenateUsing()变体必须利用特殊的常量参数(例如argument[0]argument[arguments.length-1])注入的分离器会非常不整洁。另外,我总是忘记那是哪一个。

我还想避免使用具有两个单独的子方法的取代Concatenate对象,例如Concatenate.strings()Concatenate.using()或类似方法。

这是迄今为止我失败的一些尝试......

尝试#1:

function concatenate()
{
  var result="";
  if(this.separator===undefined){var separator=false;}

  for(var i=0; i<arguments.length; i++)
  {result += arguments[i] + ((separator && (i<arguments.length-1))?separator:'');}

  this.using=function(x)
  {
    this.separator=x;
    return this;
  }

  return result;
}
Run Code Online (Sandbox Code Playgroud)

所以我想做的是:

  • 检查分隔符变量是否未定义,这意味着它尚未从子方法设置。

  • 如果未定义,则将其声明为false以便稍后评估。

  • 运行串联,如果分隔符具有除false之外的其他值,则在每个串联步骤中使用它 - 只要它不是最后一次迭代。

  • 然后返回结果。

  • 子方法.using(x)应该在某个地方设置分隔符变量的值。

当然,这是行不通的。

尝试#2:

var concatenate = function()
{
  var result="";
  var separator="";
  for(var i=0; i<arguments.length; i++)
    {result += arguments[i] + ((separator && (i<arguments.length-1))?separator:'');}
  return result;
}

concatenate.prototype.using=function(x)
{
  this.separator=x;
  return this;
}
Run Code Online (Sandbox Code Playgroud)

它也不起作用,我假设当从using()子方法返回时,concatenate ()函数的var seperator=""只是再次用 "" 覆盖该值。

我现在尝试了 4 或 5 种不同的方法,但我不想让你对所有其他方法感到厌烦。

有谁知道这个难题的解决方案吗?预先非常感谢!

Ber*_*rgi 5

你想做的事是不可能的。

\n

您不能将某些内容链接到返回原语的方法调用,因为原语没有(自定义)方法1
\n并且您不能使第一个函数根据某些内容是否链接而返回不同的内容,因为它不知道其调用上下文,并且必须在计算方法调用之前返回结果。

\n

最好的选择是返回一个可以使用自定义toString方法进行字符串化的对象,并且还提供该using功能。这将是类似的事情

\n
function concatenate() {\n    return {\n        args: Array.from(arguments), // ES6 for simplicity\n        using: function(separator) {\n            return this.args.join(separator);\n        },\n        toString: function() {\n            return this.args.join("");\n        }\n    };\n}\n\nconsole.log(String(concatenate(\'a\',\'b\',\'c\'))); // result: \'abc\'\n// alternatively, use ""+\xe2\x80\xa6 or explicitly call the \xe2\x80\xa6.toString() method\nconsole.log(concatenate(\'a\',\'b\',\'c\').using(\'-\')); // result: \'a-b-c\'\n
Run Code Online (Sandbox Code Playgroud)\n

1:不,您不想知道解决方法

\n