最常用的连接字符串的方法应该是下面几种:
// 1.=操作符
str = 'a' + 'b' + 'c';
// 2. +=操作符
str = 'a';
str += 'b';
str += 'c';
// 3. Array.join()
str = ['a', 'b', 'c'].join('');
// 4. String.concat()
str = 'a';
str = str.concat('b', 'c');
那么来看一下这几种有什么区别,或者会造成什么影响。
运行str += 'one' + 'two'
会经历以下4个过程:
onetwo
被赋值给该临时字符串;str
当前的值连接;str
。拼接这个短短的字符串就会经历以上4个步骤,那么可以进行优化吗?请看下面的代码:
// 1
str += 'one';
str += 'two';
// 2
str = str + 'one' + 'two';
以上两种方式虽然能达到同样的效果,但是却可以避免产生临时字符串(也就是4个步骤中的1&2步骤);在大多数浏览器中这样做会提速10%~40%(IE7以上,IE8效果不明显,实现机制与此不同)。
但是如果将上面的代码2换成:str = 'one' + str + 'two'
,则优化将失效。这与浏览器合并字符串时分配内存的方法有关:
除IE外,其他浏览器会尝试为表达式左侧的字符串分配更多的内存,然后简单地将第二个字符串拷贝至它的末尾。如果在一个循环中,基础字符串位于最左端的位置,就可以避免重复拷贝一个逐渐变大的基础字符串。
基本字符串可以理解为连接时排在前面的字符串。也就是说:
str + 'one'
意味着拷贝one
并附加在str
之后,而'one' + str
则意味着要拷贝str
并附加在'one'
之后,如果str
很大,拷贝过程的性能损耗(内存占用)就会很高。
说回IE8的实现机制:
在IE8的实现中,连接字符串只是记录现有的字符串的引用来构造新的字符串。在最后时刻(当你真正要使用连接后的字符串时),字符串的各个部分才会逐个拷贝到一个新的“真正的”字符串中,然后用它取代先前的字符串引用,所以并非每次使用字符串时都发生合并操作。
而IE7的实现机制更糟糕:
每连接一对字符串都要把它复制到一块新分配的内存中。
大多数浏览器中,数组项合并比其他字符串连接方法更慢
Array.join()
当把所有的数组的元素连接在一起时,浏览器会分配足够的内存来存放整个字符串,而且不会多次拷贝最终字符串中相同的部分。
字符串的原生方法concat()
能接收任意数量的参数,并将每一个参数附加到所调用的字符串上。但是多数情况下,使用concat()
比使用简单的+
和+=
稍慢,尤其在IE,Opera和Chrome中慢得更明显。
在《高性能JavaScript》看到了就记录一下,方便以后查看。