考慮JavaScript代碼的這一點點:爲什麼更改一個數組會改變另一個數組?
var a = [1, 2, 3],
b = a;
b[1] = 3;
a; // a === [1, 3, 3] wtf!?
爲什麼 「」 改變,當我更新 「B [1]」?我已經在Firefox和Chrome中測試過它。例如,這不會發生在簡單的數字上。這是預期的行爲?
var a = 1,
b = a;
b = 3;
a; // a === 1 phew!
考慮JavaScript代碼的這一點點:爲什麼更改一個數組會改變另一個數組?
var a = [1, 2, 3],
b = a;
b[1] = 3;
a; // a === [1, 3, 3] wtf!?
爲什麼 「」 改變,當我更新 「B [1]」?我已經在Firefox和Chrome中測試過它。例如,這不會發生在簡單的數字上。這是預期的行爲?
var a = 1,
b = a;
b = 3;
a; // a === 1 phew!
因爲「a」和「b」參照相同的陣列。他們中沒有兩個;將「a」的值分配給「b」將參考分配給陣列而不是 a 拷貝陣列。
當您分配號碼時,您正在處理原始類型。即使在Number實例中,也沒有辦法更新該值。
你可以看到相同的「他們指向同一個對象」與Date實例的行爲:
var d1 = new Date(), d2 = d1;
d1.setMonth(11); d1.setDate(25);
alert(d2.toString()); // alerts Christmas day
因爲數組是引用它們存儲的實際位置。
變量是指存儲對象的地方,更多的問題在這裏 – Gareth 2010-11-18 23:16:59
@Gareth這就是我所說的......數組是一個變量,當你使用數組的時候你認爲數組的方式不是用它們是如何存儲的,但是它們是如何使用的(作爲變量)。 – 2010-11-18 23:21:44
這是相同的陣列(因爲它是一個對象,它是相同的),你需要創建副本,分別操縱他們使用.slice()
(這將創建與複製的第一級元素的數組),就像這樣:
var a = [1, 2, 3],
b = a.slice();
b[1] = 3;
a; // a === [1, 2, 3]
你應該解釋爲什麼你使用切片...並且還提到副本只有一個深度 – 2010-11-18 23:16:37
@Juan - 我提供了一個直接鏈接到一些最好的文檔可用於完整的解釋,但在這裏增加了一點。 – 2010-11-18 23:17:25
感謝.slice()解決方案!這將被用於很多:) – 2010-11-18 23:33:47
除了其他的答案,如果你想要的副本數組,一種方法是使用分片方法:
var b = a.slice(0)
聲明x = y
是這裏唯一特殊的一個,它的意思是「在對象y
點變量x
。
幾乎所有其他的操作是由x
b = a;
b[1] = 3;
改變所指的對象的操作所以,你的第一條語句點在數組變量b
也被稱爲a
你的第二個語句更改b
指向的數組(以及a
)
指定數組不會創建新數組,它只是對同一個數組的引用。數字和布爾值在分配給新變量時被複制。
所有Javascript對象都通過引用傳遞 - 您需要複製整個對象,而不是分配它。
對於數組,這將是簡單的 - 只是這樣做:
var a = [1, 2, 3];
var b = a.slice(0);
其中slice(0)
返回從偏移0
到數組末尾的數組。
This link有更多信息。
有Value types和Reference types之間的差。
Basicly Value類型直接存儲在計算機「堆棧」上,這意味着您實際上具有「值」而不是所謂的指針/參考。
另一方面,引用類型不包含對象/變量的實際值,而是指向(引用)到您可以找到值的位置。
因此,當您說「我的參考類型B指向參考類型A指向的內容」時,您實際上有兩個變量指向相同的方向,當您與其中任何一個進行交互並更改某些內容時,兩者都會指向自改變的地方,因爲從開始指向相同的地方。
在另一種情況下,您會說「嘿,將變量A中的值複製到變量B中」,因此您具有單獨位置上的值,這意味着對其中任何一個的任何更改都不會影響其他值。
感謝您的好解釋!我之前沒有遇到過... – 2010-11-18 23:36:50