简介
字符串是软件中最常用的数据类型之一--它们代表了我们作为单词解析的字符串。
字符串连接是一项非常标准的任务,尤其是我们并不总是与静态字符串打交道。我们经常动态地创建字符串,比如用ES6模板,或者简单地连接字符串来形成新的字符串。
在本教程中,我们将看看如何在JavaScript中连接/追加/衔接字符串。
注意:字符串是不可变的,这意味着它们不能真正被改变。每当你在一个字符串上调用一个变化操作时,就会构造一个应用了变化的副本,并返回它而不是原来的字符串。
用+操作符串联
最简单,也可能是最直观的字符串连接应用是使用+ 操作符。
console.log("hello " + "world");
运行这段短代码的结果是
hello world
可以将内存中的字符串分配给一个引用变量,并引用该对象,而不是直接串联它。
let firstWord = "hello ";
let secondWord = "world";
let newWord = firstWord + secondWord;
这样做的结果也是
hello world
注意:在大多数情况下,你可以合理地用速记法+= 来代替= 和+ ,这样你就可以省略对第一个操作数的引用,它将被替换为你要分配结果的变量。
相反,你可以写成简写版。
let word = "hello ";
word += "world";
console.log(word);
值得注意的是,其他的数据类型也可以被扔到混合中,只要隐式转换是可能的--JavaScript就会把数据类型 "匹配 "成字符串。
例如,整数很容易转换为字符串,所以如果你试图将一个整数连接到一个字符串上--整数在被附加之前就被转换了。字符串不可能在任何时候都被转换为整数--比如当它不代表数字或有奇怪的格式时,所以一般来说,转换为字符串比从字符串转换更容易。
var str = "hello";
var int = 21;
var boolean = true;
console.log(str+int);
console.log(str+boolean)
这样做的结果是布尔值和整数都被转换为字符串表示,然后附加到 "hello "字符串上。
hello21
hellotrue
String.prototype.concat()
concat() 方法是专门为这个任务创建的--连接字符串。它可以在任何字符串上调用,并接受另一个字符串与调用的字符串进行连接。
从某种意义上说,它类似于使用简短的+= 操作符。
let string1 = "Java";
let string2 = "Script";
console.log(string1.concat(string2));
这就导致了
JavaScript
此外,你可以指定一个分隔符作为第一个参数,然后将其添加到所有串联的字符串之间。
let string1 = "Java";
let string2 = "Script";
console.log(string1.concat(", ", string2));
这个结果是
Java, Script
Array.prototype.join()
Array 类的join() 方法用于将数组中的元素连接成一个字符串,默认的分隔符是逗号(,)。
这使我们能够以更简洁的方式处理更多的字符串,把一个文件读成一个数组,或者处理一个你想连接在一起的字符串数组,这也不是没有过。
如果你没有向该方法传入任何参数--默认值将被用来给新连接的字符串定界。让我们传入一个空字符串,跳过这一点,直接连接它们,就像我们之前看到的那样。
let elements = ["JavaScript", "HTML", "CSS"];
console.log(elements.join(""));
这样的结果是
JavaScriptHTMLCSS
使用哪种方法?
由于性能上的优势,建议首选concat() 函数,而不是+运算符。然而,这实际上并不总是成立的,需要考虑到几个假设。
首先--你要连接的字符串的数量在其中起作用,还有其他你可能没有意识到的因素。让我们以concat() 方法以及+ 算子为基准。
console.time('Concatenating with Operator');
concatWithOperator();
console.timeEnd('Concatenating with Operator');
console.time('Concatenating with Function');
concatWithFunction();
console.timeEnd('Concatenating with Function');
function concatWithOperator() {
let result = "";
for (let i = 0; i < 10000; i++) {
result = result += i;
}
}
function concatWithFunction() {
let result = "";
for (let i = 0; i < 10000; i++) {
result = result.concat(i);
}
}
这样的结果是
Concatenating with Operator: 3.232ms
Concatenating with Function: 1.509ms
但是等等,让我们换个环境,在不同的机器上运行这个。
Concatenating with Operator: 1.985ms
Concatenating with Function: 1.990ms
再让我们在同一台机器上运行一下。
Concatenating with Operator: 2.030ms
Concatenating with Function: 0.934ms
执行时间差异很大(虽然,所有的速度都可以接受)。还值得注意的是MDN的官方声明,关于性能的好处。
强烈建议使用赋值运算符(+,+=)来代替concat()方法。
这可能看起来很奇怪,因为在测试中concat() ,或者在最坏的情况下,其速度与运算符相同。这是为什么呢?好吧,对这样的代码进行基准测试并不像简单地运行它和观察结果那么容易。
你的浏览器,它的版本,以及它使用的优化器可能因机器而异,像这样的属性确实会影响性能。例如,我们在连接中使用了不同的字符串,即迭代产生的字符串。如果我们使用相同的字符串,像谷歌的V8这样的优化器会进一步优化字符串的使用。
测试和验证你自己的代码,而不是听信建议。并非所有的机器和环境都是一样的,在一个机器上工作得很好的东西,在另一个机器上可能不会很好。在创建应用程序时也要考虑到这一点。
总结
我们已经看了如何在JavaScript中使用+ 操作符、Arrays 类的join() 方法以及String 类的concat() 方法来连接字符串的问题。
我们看了一下官方的立场,并进行了自己的测试,看看哪种方法是最有效的--和往常一样,这取决于各种因素。