[英]Odd javascript variable behavior with arrays
希望以前不問這個問題。 無論如何,我找不到它。 我注意到這種似乎僅在數組中發生的變量行為。
以下是我通常期望變量表現的方式。
var k = 10,
m = k;
alert(m); //10
k+=1;
alert(m); //10
現在看看它們如何處理數組。
var arr = [],
arr2 = arr;
alert(arr2); // empty
arr.push(1);
alert(arr2); // 1
似乎數組變量只是對同一數組的引用,用數字表示它們表示兩個具有相同值的不同數字。
如果這是一個菜鳥問題,很抱歉,但是我剛剛注意到了。 所有復雜類型都這樣嗎? 我想知道這種行為背后的原因。 通過這樣做,語言可以實現什么?
在您的第一個代碼塊中,您將從
+-------+ +--------------+ | k: 10 | | m: undefined | +-------+ +--------------+
然后這行:
m = k;
將k
的值復制到m
:
+-------+ +-------+ | k: 10 | | m: 10 | +-------+ +-------+
然后k+=1
更改k
的值,這對m
沒有影響:
+-------+ +-------+ | k: 11 | | m: 10 | +-------+ +-------+
在第二個代碼塊中,您將從以下內容開始:
+------+ | arr |------+ +------+ | +-----------+ +-->| (array ) | +------+ | +-----------+ | arr2 |------+ | length: 0 | +------+ +-----------+
請注意, arr
和arr2
中的值只是對數組的引用,該數組存在於內存中的其他位置。
因此,當您推送一個值時,情況將變為:
+------+ | arr |------+ +------+ | +-----------+ +-->| (array ) | +------+ | +-----------+ | arr2 |------+ | length: 0 | +------+ | 0: 1 | +-----------+
所有復雜類型都這樣嗎?
是的,所有對象(以及標准數組只是JavaScript中的對象)以及新類型的數組都是如此。
要記住的關鍵是變量具有值 。 當一個變量指物體或陣列,在變量中的值是到對象/數組的引用,而不是它的一個副本。
牢牢記住,對象引用就像(比如說)數字一樣是值,這對於理解JavaScript代碼(以及在這方面以相同方式工作的其他幾種語言的代碼,例如Java)非常有益。
以為我也可以回答為什么會這樣:
javascript中有兩種類型的值:
復雜類型通常被稱為對象:
[]
{}
new String()
new Date()
現在,原始類型為:
'a string'
23
true
因此,這里的答案是,引用在復雜類型和原始類型上的行為有所不同。
var aString = 'myString';
var refString = aString;
在此示例中,將“ aString”的值復制到refString。 它們是兩個完全獨立的值。 但是引用一個復雜的類型:
var anArray = [];
var refArray = anArray;
var anObject = {};
var refObject = anObject;
在這種情況下,兩個變量中的數組都完全相同,對象也是如此。
這也轉移到檢查相等性:
'my string' === 'my string' // true
23 === 23 // true
true === true // true
Javascript實際上只是看到這些值看起來彼此相似,而不是它在內存中是完全相同的值。 查看復雜類型:
{} === {} // false
[] === [] // false
var myObject = {};
var myObjectReferenced = myObject;
myObject === myObjectReferenced // true
這是理解JavaScript的非常重要的核心概念,否則您將有很大的風險來更改您認為獨特但實際上是共享的對象。
希望這是一個好的解釋。
兩個數組對象都指向相同的變量。 這就是為什么一個人會改變另一個會受到影響的原因
數字是javascript中的原語。 這意味着實際數據直接存儲在變量本身上。
var k = 10,
m = k;
在第一種情況下, m
和k
收到兩個不同的10副本。賦值操作復制該值,並且m上的任何更改都不會影響另一個,反之亦然(因為它們是兩個不同的副本)。
相反,數組是javascript中的引用類型
var arr = [],
arr2 = arr;
賦值操作會復制地址,因此通過一個變量對對象的任何修改都會影響另一個變量。
JavaScript(以及其他語言)中有兩種變量。 第一類保留給所謂的“原始”類型,主要是數字,字符串和布爾值。 第二種類型是“引用”類型,它是所有其他類型的對象。
您可以這樣考慮:對於基本類型,每個值都存儲在其自己的抽屜中。 例如,抽屜x的值為1,抽屜y的值為“ John”,依此類推。因此,當您訪問抽屜x時,您將直接訪問內部的值。
對於引用類型,您無需存儲變量值在抽屜本身中的指示,而僅存儲如何從隱藏在后面某處的自身內存位置中檢索此值的方向。 因此,當您將“參考抽屜”的內容復制到另一個變量時,您不是在復制值而是僅在復制方向,因此現在您有了兩個具有訪問相同值的方向的抽屜。
為什么這樣做很復雜,但是從根本上講,它與盡可能有效地管理程序的內存有關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.