但是在JavaScript中有没有常规的实现呢?
如果您需要为Internet Explorer编写代码,请确保选择使用数组连接的实现。在IE上,使用加号(+
)或加等号(+=
)运算符连接字符串非常缓慢。特别是在IE6上更是如此。在现代浏览器中,+=
通常与数组连接一样快。
当我需要进行大量字符串连接时,我通常会填充一个数组而不是使用字符串构建器类:
var html = [];
html.push(
"<html>",
"<body>",
"bla bla bla",
"</body>",
"</html>"
);
return html.join("");
请注意push
方法可以接收多个参数。
[foo(), "bar", "baz"].join("");
也可以使用。 - Anonymous不,JavaScript没有内置支持构建字符串的方法。您需要使用字符串连接代替。
当然,您可以创建一个包含字符串不同部分的数组,然后在该数组上调用 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
方法更快。
我在 Windows XP 上测试了 Internet Explorer 6,如果我尝试对超过 100,000 次的迭代进行测试,进程会立即停止响应且永远无法结束。在 40,000 次迭代中,结果是
Time (strings): 59175 ms
Time (arrays): 220 ms
这意味着 - 如果您需要支持Internet Explorer 6,请选择array.join()
,它比字符串连接方式更快。
join()
是 ECMAScript 的一部分,据我所知,每个 JavaScript 解释器都实现了它。为什么会“依赖”呢? - Eli Grey那段代码看起来就像你想要使用的路线,但需要进行一些更改。
你需要将append方法改成这样。我已经将其更改为接受数字0,并使其返回this
,这样你就可以链接你的appends了。
StringBuilder.prototype.append = function (value) {
if (value || value === 0) {
this.strings.push(value);
}
return this;
}
null
,false
,空字符串,undefined
或NaN
。 - Eli Grey编辑
不,JavaScript没有内建类。不过,字符串字面量
可能是一个合适的解决方案。
原始回答
JavaScript的ECMAScript 6版(又称ECMAScript 2015)引入了 字符串字面量。
var classType = "stringbuilder";
var q = `Does JavaScript have a built-in ${classType} class?`;
请注意,反引号(`)而不是单引号,用于括住该字符串。
尝试使用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();
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());
对于那些感兴趣的人,这里有一个替代方法来调用Array.join:
var arrayOfStrings = ['foo', 'bar'];
var result = String.concat.apply(null, arrayOfStrings);
console.log(result);
String.Format("hello {0}, your age is {1}.", "John", 29)
var x = "hello {0}, your age is {1}";
x = x.replace(/\{0\}/g, "John");
x = x.replace(/\{1\}/g, 29);
{0}
的字符串包含 {1}
,它将会出错。 - ikegami