2017-06-06 16 views
1

我遇到以下情況。我正在初始化一個數組,並將其分配給一個對象的屬性。數組賦值是否創建新的引用

var arr = [1,2,3,4,5]; 
var obj = { 'numbers': arr }; 

我明白,我通過我的數組arr參考,我的對象obj。對於意外的部分

{ numbers: [ 1, 2, 3, 4, 5, 6] } 

現在:所以我能做到以下幾點:

arr.push(6); 
console.log(obj); 

將顯示以下,符合市場預期。 arr的值通過外部事件進行更改,我希望obj.numbers的值同時更改。但事實並非如此:

arr = [0,0,0,0,0]; 
console.log(arr); 
console.log(obj); 
arr --> [0,0,0,0,0] 
obj --> { numbers: [ 1, 2, 3, 4, 5, 6] } 

所以我arr變量的值發生變化,但不是numbers財產在我obj變量。

所以,我唯一的解釋是,只要您對數組執行賦值,就會打破舊引用並創建新引用。是這樣嗎?

如何將我的新值[0,0,0,0,0]分配給我的arr變量和obj.numbers(同時)?

+0

通過'的obj = {編號:ARR}'你說 「我希望我的obj屬性'numbers'等於什麼有名爲'arr'現在」 恰好成爲陣列的參考。如果你想'obj.numbers'永遠是變量'arr'中的東西,你可以定義自定義getter'obj = {get numbers(){return arr}}'。現在你可以說'arr =「blah」'和'obj.numbers'將返回在訪問屬性的時候'arr'持有的任何東西。 –

回答

2

是的,與=的任務創建一個新的參考,並擺脫舊的。爲了解決這個問題:

var arr = [1, 2, 3, 4, 5]; 
 
    var obj = { 'numbers': arr }; 
 
    console.log(arr === obj.numbers); // -> true 
 

 
    arr.length = 0; 
 
    var newArr = [0, 0, 0, 0, 0]; 
 
    arr.push(...newArr); 
 
    console.log(arr === obj.numbers); // -> true 
 
    console.log(arr); // -> [0, 0, 0, 0, 0]

設置長度等於0,則該陣列。將項目推入數組時,它不會創建新數組,因此您會看到arrobj兩個變化。

0

我還沒有找到關於此的確切文檔,但經過一些實驗後,我得出結論,一個任務確實創建了一個新的參考。

這是我最終解決這個問題的方法。

arr.splice(0); 
[0,0,0,0,0].map(el => arr.push(el); 

這給了我下面的預期結果。

console.log(arr); 
console.log(obj); 
arr --> [0,0,0,0,0] 
obj --> { numbers: [0,0,0,0,0] } 

順便說,同樣是對於對象,這將是合乎邏輯的,因爲陣列是一種類型的對象的真實。

+1

'arr.slice(0);'這沒有意義W/O分配。 'slice'創建* new *數組保持原始數組完好無損。所以既然你不存儲結果基本上這個操作只會加熱你的CPU。然後''0,0,0,0,0] .map(el => arr.push(el))'語義上應該''map'應該被用來創建具有「映射」項目的新數組。既然你沒有任務,你最好使用'forEach'。 –

+0

我打算使用拼接 –

0

它的工作原理正確。變量是您保存參考的地方。您保存在arr另一個參考。

您可以使用此代碼更新第一個數組。

arr.length = 0; 
arr.push(...[0, 0, 0, 0, 0]); 

slice方法不會幫助你,因爲它返回數組的新副本。

+0

您正在將數組推入'arr',所以'arr'現在看起來像'[[0,0,0,0,0]]'。這不是問題的要求。 –

+0

@ArnavAggarwal你是對的。我修復了它。 –

1

你也可以使用Array#splice來創建一個新的數組。

var array = [1,2,3,4,5], 
 
    object = { numbers: array }, 
 
    newArray = [41, 42, 43]; 
 

 
[].splice.apply(array, [0, array.length].concat(newArray)); 
 

 
console.log(object);