在 JavaScript 中进行字符串构建/连接的最佳方法是什么?

IT技术 javascript string concatenation conventions
2021-02-09 16:17:17

JavaScript 是否支持替换/插值?

概述


我正在做一个 JS 项目,随着它变得越来越大,保持字符串的良好状态变得越来越困难。我想知道在 JavaScript 中构造或构建字符串的最简单和最传统的方法是什么。

到目前为止我的经验:

随着项目变得越来越复杂,字符串连接开始看起来很丑陋,并且变得更难维护。

在这一点上最重要的是简洁和可读性,想想一堆活动的部分,而不仅仅是 2-3 个变量。

到目前为止,主流浏览器都支持它也很重要(即至少支持 ES5)。

我知道 JS 连接速记:

var x = 'Hello';
var y = 'world';
console.log(x + ', ' + y);

以及String.concat函数。

我正在寻找更整洁的东西。

Ruby 和 Swift 以一种有趣的方式做到了这一点。

Ruby

var x = 'Hello'
var y = 'world'
print "#{x}, #{y}"

迅速

var x = "Hello"
var y = "world"
println("\(x), \(y)")

我在想 JavaScript 中可能有类似的东西,可能类似于sprintf.js

问题


这可以在没有任何第三方库的情况下完成吗?如果没有,我可以使用什么?

6个回答

使用 ES6,您可以使用

  • 模板字符串

    var username = 'craig';
    console.log(`hello ${username}`);
    

ES5及以下:

  • 使用+运算符

    var username = 'craig';
    var joined = 'hello ' + username;
    
  • 字符串的 concat(..)

    var username = 'craig';
    var joined = 'hello '.concat(username);
    

或者,使用数组方法:

  • join(..)

    var username = 'craig';
    var joined = ['hello', username].join(' ');
    
  • 甚至更高级,reduce(..)结合以上任何一项:

    var a = ['hello', 'world', 'and', 'the', 'milky', 'way'];
    var b = a.reduce(function(pre, next) {
      return pre + ' ' + next;
    });
    console.log(b); // hello world and the milky way
    
@MMagician 是的,我第一次尝试时完全错过了后撑
2021-04-03 16:17:17
这个答案并不建议“最好”。所以对我来说,前两个是非常快速和可读的,为了决定我检查了大公司是怎么做的,我倾向于模板文字 github.com/airbnb/javascript#es6-template-literals
2021-04-06 16:17:17
对于 ES6 模板字符串,请注意使用反引号 (``) 而不是 '' 或 "" ( developers.google.com/web/updates/2015/01/... )
2021-04-07 16:17:17

我很失望其他答案中没有人将“最佳方式”解释为“最快方式”......

我从这里提取了 2 个示例,str.join()str.reduce()上面nishanths 的回答中添加了这是我在 Linux 上的 Firefox 77.0.1 上的结果。


注意:我在测试这些时发现,如果我将str = str.concat()str +=直接放在彼此之前或之后,第二个总是表现得更好......所以我单独运行这些测试并评论其他结果......

尽管如此如果我重新运行它们,它们的速度差异很大,所以我为每个测量了 3 次。

一次 1 个字符:

  • str = str.concat()841, 439, 956 ms / 1e7 concat()'s
  • ............str +=949, 1130, 664 ms / 1e7 +='s
  • .........[].join()3350, 2911, 3522 ms / 1e7 characters in []
  • .......[].reduce()3954, 4228, 4547 ms / 1e7 characters in []

一次 26 个字符串:

  • str = str.concat()444, 744, 479 ms / 1e7 concat()'s
  • ............str +=1037, 473, 875 ms / 1e7 +='s
  • .........[].join()2693, 3394, 3457 ms / 1e7 strings in []
  • .......[].reduce()2782, 2770, 4520 ms / 1e7 strings in []

因此,无论是一次附加 1 个字符还是一次 26 个字符串:

  • 明显的赢家:基本上是str = str.concat()之间的平局str +=
  • 清除失败者:[].reduce(),其次是[].join()

我的代码,易于在浏览器控制台中运行:

{
  console.clear();

  let concatMe = 'a';
  //let concatMe = 'abcdefghijklmnopqrstuvwxyz';

  //[].join()
  {
    s = performance.now();
    let str = '', sArr = [];
    for (let i = 1e7; i > 0; --i) {
      sArr[i] = concatMe;
    }
    str = sArr.join('');
    e = performance.now();
    console.log(e - s);
    console.log('[].join(): ' + str);
  }

  //str +=
  {
    s = performance.now();
    let str = '';
    for (let i = 1e7; i > 0; --i) {
      str += concatMe;
    }
    e = performance.now();
    console.log(e - s);
    console.log('str +=: ' + str);
  }

  //[].reduce()
  {
    s = performance.now();
    let str = '', sArr = [];
    for (let i = 1e7; i > 0; --i) {
      sArr[i] = concatMe;
    }
    str = sArr.reduce(function(pre, next) {
      return pre + next;
    });
    e = performance.now();
    console.log(e - s);
    console.log('[].reduce(): ' + str);
  }

  //str = str.concat()
  {
    s = performance.now();
    let str = '';
    for (let i = 1e7; i > 0; --i) {
      str = str.concat(concatMe);
    }
    e = performance.now();
    console.log(e - s);
    console.log('str = str.concat(): ' + str);
  }

  'Done';
}

我得到了类似的结果。''.concat(...strings)始终优于所有其他方法。我想知道为什么它没有得到应有的爱。
2021-04-02 16:17:17
var descriptor = 'awesome';
console.log(`ES6 is ${descriptor}!`);

更多:https : //developers.google.com/web/updates/2015/01/ES6-Template-Strings?hl=en

截至目前(2020 年 3 月),所有主要浏览器都支持 ES6,因此您可以自由使用它,除非您需要支持旧的、过时的、糟糕的浏览器(即 Internet Explorer)
2021-03-18 16:17:17
我希望这部作品会很棒!,但目前仅在 chrome 中受支持 :L 很好的答案:)
2021-03-24 16:17:17
还有 Firefox 和 Opera。:) 只是不是 IE 或 Safari。
2021-04-12 16:17:17

我认为replace()在这里值得一提。

在某些情况下,replace 方法在构建字符串时可以很好地为您服务。具体来说,显然,当您将动态部分注入其他静态字符串时。例子:

var s = 'I am {0} today!';
var result = s.replace('{0}', 'hungry');
// result: 'I am hungry today!'

要替换的占位符显然可以是任何东西。我出于 C# 的习惯使用“{0}”、“{1}”等。它只需要足够独特,不会出现在预期之外的字符串中。

因此,如果我们可以稍微处理一下字符串部分,OP 示例也可以这样解决:

var x = 'Hello {0}';
var y = 'World';
var result = x.replace('{0}', y);
// result: 'Hello World'. -Oh the magic of computing!

“替换”参考:https : //www.w3schools.com/jsreF/jsref_replace.asp

您可以使用该concat功能。

var hello = "Hello ";
var world = "world!";
var res = hello.concat(world);
如果hello没有尾随空格,您将如何在同一行中实现所有这些?hello.concat(world.concat(' '));? 或者你仍然会使用速记和做hello.concat(' ' + world)
2021-03-27 16:17:17
@MrHazeconcat采用可变数量的参数。那么,也许,str1.concat.apply(null, [str2, str3, str4])稍微提高了可读性?
2021-03-30 16:17:17
@MikeStoddart 我在回答这个问题时可能已经很晚了,但正如这篇文章中的另一个答案所说,与 .concat 相比,[...].join 和 .reduce 的字符串连接速度都非常慢,但是我想补充一点带有字符串插值 ( hello there ${name}) 的新 ES6 方式更简洁,也非常高效
2021-04-08 16:17:17
如果我想用 6 个不同的移动部件构建一个更长的字符串,那么使用 concat 函数根本无法读取它。
2021-04-10 16:17:17
str1.concat.apply(null, [str2, str3, str4]) <-- 与使用 [...].join('') 相比,它的性能如何?
2021-04-11 16:17:17