如何在JavaScript里拼接字符串?
如果你有Java或其他语言的编程经验,那么可能会疑惑,在JavaScript里,没有StringBuilder之类的类或对象可以用,那么如何拼接字符串才是高效的呢?
一般来讲,JavaScript里拼接字符串有4种方式:
1. 使用+
运算符来拼接
这种方式比较常见,用+将字符串连起来,得到一个新的字符串。
const s1 = "Hello";
const s2 = "乐码范!";
const result = s1 + " " + s2;
console.log(result); // Hello 乐码范! Again!
这种方法,可能许多编程老手会说有性能问题,理由是字符串是不可变的,因此每次拼接操作都会重新创建一个新的字符串。在每一次拼接大量字符串的时候,都会产生内存申请及回收操作,当字符串很长的时候,会很耗内存,导致代码性能很低。
其实,这在JavaScript里是个老观念了,因为现代的JavaScript引擎已经对这种场景做了优化,性能不再是一个问题。稍后我们再来看性能比较。
2. 使用concat()
方法
string对象有个concat()
方法可以用来拼接字符串:
const s1 = "Hello";
const s2 = "乐码范!";
const result = s1.concat(" ", s2);
console.log(result); // Hello 乐码范!
3. 使用Array.join()
方法
JavaScript里的数组有个join()方法,可以将数组里面的字符串合成一个字符串。
const result = ["Hello", "乐码范!"].join(" ");
console.log(result); // Hello 乐码范!
这种方法可以用来做大量字符串的合并,是传统上性能比较高的方法。
4. 使用模版字符串(Template literals)
在ES5里面,JavaScript引入了一个新的叫做模版字符串的语法,使用反引号```来格式化一个字符串。
const s1 = "Hello";
const s2 = "乐码范!";
const result = `${s1} ${s2}`;
console.log(result); // Hello 乐码范!
上面的代码和第一种使用+号的方式来比,我们很容易看出最终字符串result的结构,因此更容易读。关于模版字符串的语法,可以参考MDN。
比较一下性能
由于模版字符串主要用于拼接数量有限的几个变量,所以在拼接大量字符串的时候,我们不会用它。所以这里只是比较一下前三种的性能(下面的代码可以拷贝到您的本地运行):
const s1 = "Hello 乐码范!";
const count = 1000000;
// 生成测试数据
const data = [];
for (let i = 0; i < count; i++) {
data.push(s1 + i);
}
console.time('加号拼接')
let result = '';
for (let i = 0; i < count; i++) {
result = result + data[i];
}
console.timeEnd('加号拼接');
console.time('concat()拼接')
result = '';
for (let i = 0; i < count; i++) {
result = result.concat(data[i]);
}
console.timeEnd('concat()拼接');
console.time('Array.join()拼接')
result = '';
const values = [];
for (let i = 0; i < count; i++) {
values.push(data[i]);
}
result = values.join();
console.timeEnd('Array.join()拼接');
这个结果,在同一台电脑上,Node.js v14和Chrome浏览器里面跑的一次结果是这样的:
拼接方式 | Node.js V14 (毫秒) | Chrome V92 (毫秒) |
---|---|---|
加号拼接 | 121.78 | 92.64 |
concat()拼接 | 116.99 | 67.44 |
Array.join()拼接 | 142.75 | 137.48 |
由此可以看出,三种方式concat()是最快的,但是三种方式的性能,不管是在Node.js还是Chrome浏览器上,实际是差不多的。虽有差异,但偶尔跑的结果顶多是一两倍的差异,而不是数量级上的差异。
因此,在实际写代码的时候,完全可以根据场景和习惯来使用,不用考虑上面不同的写法造成的性能上的差异。