2014-01-20 34 views
2

讓我們說我有一個數組,var animals = ["dog","cat","rat"];通過參考解決方法的JavaScript通

然後我定義var pets = animals;

然後我打電話pets.shift();

現在因爲JavaScript是通過按引用數組,如果我現在撥打animals,我會得到["cat","rat"]

我的問題:有沒有辦法解決這個問題,如果我稍後想以未修改的形式使用animals

回答

7

關於術語的說明:JavaScript是從不pass-by-reference(不管你聽到有多少人說這是)。當你寫了一行:

var pets = animals; 

你分配的animalspets。分配的值是對數組的引用,因此現在兩個變量都將指向內存中的同一對象。 (注意:這有些迂腐,但它也有正確的好處。)

如果你想讓這兩個變量引用兩個不同的數組,那麼你需要創建一個原始副本數組並將其分配給pets。要做到這一點在JavaScript中最常見的方式是採取的事實,即一些陣列方法(如sliceconcat)創建數組的副本上,他們是所謂:

var pets = animals.concat(); 

證明的/平等:

var arr = []; 
arr1 = arr; 
console.log(arr1 === arr); // true 
console.log(arr1 === arr.concat()) // false 

當然,您也可以自己進行復制:

function copy(arr) { 
    var i, len = arr.length, arr1 = new Array(len); 
    for (i = 0; i < len; i += 1) { 
     arr1[i] = arr[i]; 
    } 
    return arr1; 
} 

事實上,this is probably a lot faster並應被視爲˚F或非常大的陣列。 (在大多數情況下,只需做最可讀的操作。)

請注意,每種方法都會創建一個副本的原始數組。如果數組持有對其他對象的引用,那麼這些引用將被複制到新數組中(即,原始數組和新數組都將引用相同的對象)。另一方面,字符串和數字直接複製到新數組中。

+0

感謝您的徹底解答。一個微妙的區別,我會花一些時間來包裝我的大腦。 –

+0

所以 - 如果複製數組包含和對象,然後修改,我可以有同樣的問題。 –

+0

是的。你可能想看看這裏:http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object –

3

你要克隆的陣列,它與

var savedAnimals = animals.slice(); 

請注意,這不是一個深克隆完成:它不保護元件內部對修改(如果他們不是字符串) 。

+0

是的,這是有效的。謝謝!任何其他策略? –

+0

這是最好的,這是標準的。 –