最常用的連線字串的方法應該是下面幾種:
// 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() 和 String.prototype.concat()
大多數瀏覽器中,陣列項合併比其他字串連線方法更慢
Array.join()
當把所有的陣列的元素連線在一起時,瀏覽器會分配足夠的記憶體來存放整個字串,而且不會多次拷貝最終字串中相同的部分。
字串的原生方法concat()
能接收任意數量的引數,並將每一個引數附加到所呼叫的字串上。但是多數情況下,使用concat()
比使用簡單的+
和+=
稍慢,尤其在IE,Opera和Chrome中慢得更明顯。
在《高效能JavaScript》看到了就記錄一下,方便以後檢視。