2017-08-10 78 views
3

考慮下面的javascript代碼,爲什麼array.push()似乎推動無限次?

>> a = [1, 2] 
    Array [ 1, 2 ] 

>> a.push(a) 
    Array [ 1, 2, Array[3] ] 

擴大陣列,a,我們得到了無限深度的陣列。 (在Firefox開發者控制檯上查看)

Array[3] 
| 0: 1 
| 1: 2 
    2: Array[3] 
    | 0: 1 
    | 1: 2 
    | 2: Array[3] 
    | 0: 1 
    | 1: 2 
    | 2: Array[3] 
    .... 

[1]爲什麼要多次追加?
[2]它停止的深度是多少?

+3

循環引用也許可以解釋這一點。 – Manish

+2

要理解遞歸,您必須先了解遞歸。 –

回答

3

它只是推一次。當數組引用自身時(circular refernce),您會看到多個插入的數組。顯示取決於瀏覽器。

如果你試圖讓一個JSON字符串,然後JSON.stringify打破了一個錯誤

Circular reference in value argument not supported 

var a = [1, 2] 
 
console.log(a); 
 

 
a.push(a); 
 
console.log(a); 
 
JSON.stringify(a);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+1

SO整齊地解析了引用,並將它們顯示在'**'中。 +1 :) – 31piy

+0

所以實際的輸出是'[1,2,[1,2]]'對嗎? – TheChetan

+1

,但引用了外部數組和第三個元素在內部數組中,數組本身就像'[1,2,[1,2,[1,2,[1,2,...]] ]]'但實際上它只存儲'[1,2,對數組的引用]'。 –

0

因爲javascript給出的是'a'變量的引用,而不是實際的對象,所以如果你將a推到自己,你推存儲器地址保存對象,並創建一個循環引用。

[1,2,參照該對象]

+0

什麼?請多解釋一下。 – PeterMader

+0

當你創建var a = [1,2]對象時,當你說var b = a時,'a'保存內存地址信息whats持有對象[1,2]您傳遞引用,即包含[1,2]數組對象的內存地址。所以如果你說b。推(3)它會添加到該對象的其他項目它將[1,2,3],但地址不會改變,所以現在a和b等於[1,2,3],如果你cal a。推(一)它意味着你有一個對象,它是[1,2,*內存地址本身*],所以你可以去越來越深,因爲它將是相同的對象 –

+0

我知道。這被稱爲循環參考。你爲什麼不把它添加到你的答案?現在,這聽起來有點混亂。 – PeterMader

0

它實際上是推動它一次。它不會推送數組元素,而是數組的地址。 Firefox控制檯只是試圖顯示那裏的內容,但最終會無限地顯示相同的內容。

不僅僅是Firefox,Chrome也是如此。

1

它沒有被推到無數次。這是Firefox開發者控制檯如何呈現元素的問題。展開數組並再次單擊它,將自己始終顯示數組的外觀。因此,您可以將其展開並單擊無限次數,但仍然有只有一次

1

你已經創建了一個循環引用。

將數組推到自身上時,數組中的最後一個元素成爲對整個數組的引用 - 包括最後一個元素。因此,最後一個元素中的最後一個元素也是對整個數組的引用,依此類推。

無限的圓圈是無限的,並且「附加多於一次」的意思是,如果你不止一次地繞過一個圓圈,你將不止一次碰到同一個點。

相關問題