簡體   English   中英

數組的奇怪JavaScript變量行為

[英]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 |
+------+          +-----------+

請注意, arrarr2中的只是對數組的引用,該數組存在於內存中的其他位置。

因此,當您推送一個值時,情況將變為:

+------+
| arr  |------+
+------+      |   +-----------+
              +-->| (array )  |
+------+      |   +-----------+
| arr2 |------+   | length: 0 |
+------+          | 0: 1      |
                  +-----------+

所有復雜類型都這樣嗎?

是的,所有對象(以及標准數組只是JavaScript中的對象)以及新類型的數組都是如此。

要記住的關鍵是變量具有 當一個變量指物體或陣列,在變量中的是到對象/數組的引用,而不是它的一個副本。

牢牢記住,對象引用就像(比如說)數字一樣是值,這對於理解JavaScript代碼(以及在這方面以相同方式工作的其他幾種語言的代碼,例如Java)非常有益。

以為我也可以回答為什么會這樣:

javascript中有兩種類型的值:

  1. 復雜類型
  2. 原始類型

復雜類型通常被稱為對象:

[]
{}
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;

在第一種情況下, mk收到兩個不同的10副本。賦值操作復制該值,並且m上的任何更改都不會影響另一個,反之亦然(因為它們是兩個不同的副本)。

相反,數組是javascript中的引用類型

var arr = [],
    arr2 = arr;

賦值操作會復制地址,因此通過一個變量對對象的任何修改都會影響另一個變量。

JavaScript(以及其他語言)中有兩種變量。 第一類保留給所謂的“原始”類型,主要是數字,字符串和布爾值。 第二種類型是“引用”類型,它是所有其他類型的對象。

您可以這樣考慮:對於基本類型,每個值都存儲在其自己的抽屜中。 例如,抽屜x的值為1,抽屜y的值為“ John”,依此類推。因此,當您訪問抽屜x時,您將直接訪問內部的值。

對於引用類型,您無需存儲變量值在抽屜本身中的指示,而僅存儲如何從隱藏在后面某處的自身內存位置中檢索此值的方向。 因此,當您將“參考抽屜”的內容復制到另一個變量時,您不是在復制值而是僅在復制方向,因此現在您有了兩個具有訪問相同值的方向的抽屜。

為什么這樣做很復雜,但是從根本上講,它與盡可能有效地管理程序的內存有關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM