2017-09-13 41 views
4

鑑於以下代碼的新的數組:在陣列中按字符串元素的參考串

var old_Array =["One","Two","..."]; 
    var len = old_Array .length; 
    var new_Array =[]; 
    for(var i=0;i<len;++i) 
    { 
     new_Array.push(old_Array [i]); // ----- [1] 
    } 

後[1]new_Array填充有字符串。

  1. 是每個元素實際上是在 old_Array,字符串元素引用或複製每個字符串元素?
  2. 是否JavaScript解釋器/編譯器優化線 - [1]通過 在old_Array每個字符串元素的推引用?
+5

只有通過引用傳遞對象,纔會複製類似字符串的基元。 –

+0

@PatrickEvans感謝您的快速答覆。但JavaScript引擎優化該代碼行嗎?因爲該字符串對象的內存分配已經存在於old_Array中了......我們是否可以傳達編譯器,我們需要在那裏進行優化......而不是每個元素的深度複製或淺拷貝 – Buddhika

+0

想想old_Array是否有大量的字符串元素。許多複製操作將會發生。 – Buddhika

回答

1

對第一個問題的回答:每個元素只是舊數組的每個字符串元素的副本。 如果數組包含對象引用,則將引用複製到新數組中。 (在這種情況下,像字符串和數字這樣的基本類型被按值複製。)

對第二個問題的回答:不,JavaScript解釋器不會通過推送old_Array中每個字符串元素的引用來優化行[1] 。

更快和更好的方法來複制的陣列是:

var new_Array = old_Array.slice(); 

它克隆舊數組,並返回參照新的數組。

+1

謝謝.yeah slice()與克隆的概念一起工作。當你考慮每個兩個數組的基數時,認爲你想在new_Array內部有old_array元素的一部分,爲了表示的目的,我們可以有new_Array結構,如果我們有100000舊數組中的字符串元素,當我們必須使用5000個而不是克隆時,我們創建新的數組結構,其中5000個數據已經存在於舊數組中,因此,而不是5000次複製操作,我們可以直接指定數據的內存位置,已通過引用存在於舊數組中。 – Buddhika

+0

@Buddhika在這種情況下,你必須確保舊的數組不會被刪除。另外,如果元素大小較小,將元素複製到新數組將更有意義。如果數組元素的大小過大,則通過引用訪問它們將是最佳選擇。 –

1

有趣的問題。事情是字符串是不可變的,這意味着一旦它們寫在內存中,它們不能被改變。所以,當你不喜歡

var s2 = s.substr(0, 3); 

s2現在是一個新的字符串,但它不會複製到新的存儲位置,而不是代表就像s一個範圍。因此,根據你的問題,從一個字符串數組複製一個字符串不應該爲新字符串分配額外的內存。但是,當原始字符串的數組不再需要時,GC應該足夠聰明,以確定要從該數組分配的內存中刪除哪些項目。

我猜這些實現會根據JS引擎而改變。這裏有關於此主題的MDN的一些信息。

+0

感謝您的關注和答覆。 – Buddhika

+0

順便說一下,只要s2不會被改變,它可以表示爲s的範圍,但是如果我們假設javascript解釋器/編譯器有深入的代碼分析和運行時檢查,它可以優化s2,就像range用新的內存分配來代替新的String的表示,但是如果它檢測到對s2的任何修改,它會分配新的內存嗎? – Buddhika

+0

@Buddhika's2'會發生什麼樣的變化..?記住's2'也是不可變的。唯一可能發生的情況是在沒有更多代碼被引用時被垃圾收集器(GC)刪除。 – Redu