230

我看到了一些代码项目解决方案

但是在 JavaScript 中有一个常规的实现吗?

4

12 回答 12

365

如果您必须为 Internet Explorer 编写代码,请确保您选择了一个使用数组连接的实现。+在 IE 上使用or运算符连接字符串+=非常慢。对于 IE6 尤其如此。在现代浏览器+=上,通常与数组连接一样快。

当我必须进行大量字符串连接时,我通常会填充一个数组并且不使用字符串构建器类:

var html = [];
html.push(
  "<html>",
  "<body>",
  "bla bla bla",
  "</body>",
  "</html>"
);
return html.join("");

请注意,这些push方法接受多个参数。

于 2010-01-18T16:42:41.563 回答
66

我刚刚重新检查了http://jsperf.com/javascript-concat-vs-join/2上的性能。测试用例连接或连接字母表 1,000 次。

在当前的浏览器(FF、Opera、IE11、Chrome)中,“concat”比“join”快大约 4-10 倍。

在 IE8 中,两者都返回大致相同的结果。

不幸的是,在 IE7 中,“加入”的速度大约快了 100 倍。

于 2014-11-25T12:08:33.287 回答
42

不,没有对构建字符串的内置支持。您必须改用串联。

当然,您可以创建一个包含字符串不同部分的数组,然后调用join()该数组,但这取决于您在使用的 JavaScript 解释器中如何实现连接。

我做了一个实验来比较str1+str2方法与array.push(str1, str2).join()方法的速度。代码很简单:

var iIterations =800000;
var d1 = (new Date()).valueOf();
str1 = "";
for (var i = 0; i<iIterations; i++)
    str1 = str1 + Math.random().toString();
var d2 = (new Date()).valueOf();
log("Time (strings): " + (d2-d1));

var d3 = (new Date()).valueOf();
arr1 = [];
for (var i = 0; i<iIterations; i++)
    arr1.push(Math.random().toString());
var str2 = arr1.join("");
var d4 = (new Date()).valueOf();
log("Time (arrays): " + (d4-d3));

我在 Windows 7 x64 上的 Internet Explorer 8 和 Firefox 3.5.5 中对其进行了测试。

一开始,我测试了少量迭代(几百个,几千个项目)。结果是不可预测的(有时字符串连接需要 0 毫秒,有时需要 16 毫秒,数组连接也是如此)。

当我将计数增加到 50,000 时,不同浏览器的结果有所不同 - 在 Internet Explorer 中,字符串连接更快(94 毫秒),连接更慢(125 毫秒),而在 Firefox 中,数组连接更快(113 毫秒)字符串连接(117 毫秒)。

然后我将计数增加到 500'000。现在array.join()在两个浏览器中都比字符串连接慢:字符串连接在 Internet Explorer 中为 937 毫秒,在 Firefox 中为 1155 毫秒,在 Internet Explorer 中数组连接为 1265,在 Firefox 中为 1207 毫秒。

我可以在 Internet Explorer 中测试而没有“脚本执行时间过长”的最大迭代次数是 850,000。然后 Internet Explorer 的字符串连接为 1593,数组连接为 2046,Firefox 的字符串连接为 2101,数组连接为 2249。

结果- 如果迭代次数很少,您可以尝试使用array.join(),因为它在 Firefox 中可能更快。当数量增加时,该string1+string2方法更快。

更新

我在 Internet Explorer 6 (Windows XP) 上进行了测试。如果我在超过 100,000 次迭代中尝试测试,该过程会立即停止响应并且永远不会结束。在 40,000 次迭代中,结果为

Time (strings): 59175 ms
Time (arrays): 220 ms

这意味着 - 如果您需要支持 Internet Explorer 6,请选择array.join()比字符串连接更快的方式。

于 2010-01-18T16:31:52.570 回答
10

该代码看起来像您要进行一些更改的路线。

您需要将 append 方法更改为如下所示。我已将其更改为接受数字 0,并使其返回this,以便您可以链接附加内容。

StringBuilder.prototype.append = function (value) {
    if (value || value === 0) {
        this.strings.push(value);
    }
    return this;
}
于 2010-01-18T16:43:20.440 回答
5

编辑

不,没有内置类。但是,string literals可能是一个合适的解决方法。

原始答案

JavaScript 的 ECMAScript 6 版本(又名 ECMAScript 2015)引入了字符串文字

var classType = "stringbuilder";
var q = `Does JavaScript have a built-in ${classType} class?`;

请注意,反引号而不是单引号将字符串括起来。

于 2018-02-02T15:34:59.733 回答
3

我已经定义了这个函数:

function format() {
        var args = arguments;
        if (args.length <= 1) { 
            return args;
        }
        var result = args[0];
        for (var i = 1; i < args.length; i++) {
            result = result.replace(new RegExp("\\{" + (i - 1) + "\\}", "g"), args[i]);
        }
        return result;
    }

并且可以像 c# 一样调用:

 var text = format("hello {0}, your age is {1}.",  "John",  29);

结果:

你好,约翰,你的年龄是 29 岁。

于 2018-06-06T19:50:25.793 回答
2

用于 JavaScript 的 StringBuilder 试试这个..

  
function StringBuilder(value) {
    this.strings = new Array();
    this.append(value);
}

StringBuilder.prototype.append = function (value) {
    if (value) {
        this.strings.push(value);
    }
}

StringBuilder.prototype.clear = function () {
    this.strings.length = 0;
}

StringBuilder.prototype.toString = function () {
    return this.strings.join("");
}

var sb = new StringBuilder();
sb.append("This is");
sb.append("much better looking");
sb.append("than using +=");

var myString = sb.toString();

sb.clear();

于 2021-08-07T18:07:11.473 回答
1

对于那些感兴趣的人,这里是调用 Array.join 的替代方法:

var arrayOfStrings = ['foo', 'bar'];
var result = String.concat.apply(null, arrayOfStrings);
console.log(result);

正如预期的那样,输出是字符串“foobar”。在 Firefox 中,这种方法优于 Array.join,但优于 + 连接。由于 String.concat 要求将每个段指定为单独的参数,因此调用者受到执行 JavaScript 引擎施加的任何参数计数限制的限制。查看Function.prototype.apply() 的文档以获取更多信息。

于 2014-03-31T22:21:21.430 回答
1

下面是 Typescript 中 StringBuilder 类的一个简单示例:

export class StringBuilder {
  private _lines: string[] = [];

  write(line: string = ""): void {
    this._lines.push(line);
  }

  writeln(line: string = ""): void {
    this._lines.push(line);
    this._lines.push("\n");
  }

  toString(): string {
    return this._lines.join("");
  }
}

你可以像下面这样使用:

const sb = new StringBuilder();
sb.write("Hello World");
sb.writeln("!");
console.log(sb.toString());
于 2022-01-06T00:27:58.753 回答
0

当我发现自己在 JavaScript 中做了很多字符串连接时,我开始寻找模板。Handlebars.js 可以很好地保持 HTML 和 JavaScript 的可读性。http://handlebarsjs.com

于 2016-01-12T12:45:20.747 回答
0

在 C# 中,您可以执行类似的操作

 String.Format("hello {0}, your age is {1}.",  "John",  29) 

在 JavaScript 中,你可以做类似的事情

 var x = "hello {0}, your age is {1}";
 x = x.replace(/\{0\}/g, "John");
 x = x.replace(/\{1\}/g, 29);
于 2017-06-07T17:30:43.433 回答
-1

sys.StringBuilder()试试下面的文章怎么样。

https://msdn.microsoft.com/en-us/library/bb310852.aspx

于 2017-05-29T08:17:31.740 回答