2017-04-26 71 views
2

我想更好地瞭解如何通過引用傳遞作品有關拼接。我想有一個主要的對象數組,並使用另一個數組引用主數組對象。例如:通過引用和拼接

var mainArray = [ 
    someObject, 
    anotherObject 
] 
var subArray = []; 
subArray.push(mainArray[ 0 ]); 

我不明白的是如果我拼接原始值會發生什麼?

mainArray.splice(0, 1); 

不子陣[0]:

  1. 也得到拼接?
  2. 由於有指針,它的值依然存在嗎?
  3. 剩下一個空值?
+1

有**是沒有**傳遞通過引用在JavaScript中。術語「通過引用」在編程中具有特定的含義(這是「藝術術語」):將引用*傳遞給變量*到函數中。 JavaScript沒有。 –

+1

上面你正在做的是將一個對象引用傳遞給一個函數(按值,該值是對象引用)。 –

+0

不,是(但正如TJ所說,「指針」是值),沒有...... – RobG

回答

4

此代碼後:

var mainArray = [ 
    someObject, 
    anotherObject 
]; 
var subArray = []; 
subArray.push(mainArray[ 0 ]); 

...你有什麼樣的內存看起來有點像這樣:

 
                +−−−−−−−−−−+ 
someObject−−−−−−−−−−−−−−−−−−+−−+−−−−−−−−−−−−−−−−−−>| (object) | 
         //     +−−−−−−−−−−+ 
          | |  
          | |      +−−−−−−−−−−+ 
          | | anotherObject−−−+−>| (object) | 
          | |    / +−−−−−−−−−−+ 
          | |    | 
      +−−−−−−−−−−−+ | |    | 
subArray−−−−>| (array) | | |    | 
      +−−−−−−−−−−−+ | |    | 
      | length: 1 | | |    | 
      | 0:  |−/ |    | 
      +−−−−−−−−−−−+ |    | 
           |    | 
       +−−−−−−−−−−−+ |    | 
mainArray−−−−>| (array) | |    | 
       +−−−−−−−−−−−+ |    | 
       | length: 2 | |    | 
       | 0:  |−−/     | 
       | 1:  |−−−−−−−−−−−−−−−−−−−−/ 
       +−−−−−−−−−−−+ 

注意,有mainArraysubArray根本沒有聯繫。它們都恰好包含相同的值(這也是someObject中的值,所有三個地方都有同一對象的對象引用)。

去除mainArray該值對subArray(或物體)沒有影響:

mainArray.splice(0, 1); 
 
                +−−−−−−−−−−+ 
someObject−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−−−−−−−−>| (object) | 
         /      +−−−−−−−−−−+ 
          |  
          |      +−−−−−−−−−−+ 
          |  anotherObject−−−+−>| (object) | 
          |     / +−−−−−−−−−−+ 
          |     | 
      +−−−−−−−−−−−+ |     | 
subArray−−−−>| (array) | |     | 
      +−−−−−−−−−−−+ |     | 
      | length: 1 | |     | 
      | 0:  |−/     | 
      +−−−−−−−−−−−+      | 
               | 
       +−−−−−−−−−−−+     | 
mainArray−−−−>| (array) |     | 
       +−−−−−−−−−−−+     | 
       | length: 1 |     | 
       | 0:  |−−−−−−−−−−−−−−−−−−−−/ 
       +−−−−−−−−−−−+ 

所以基於這樣:

1.也得到拼接?

不,更改mainArary的內容對subArray沒有影響。

2.由於存在指針,該值依然存在嗎?

subArray的條目值0不受影響。

3.剩下一個空值?

不,根本不影響subArray


我想更好地瞭解如何通過參考書相對於拼接通過。

你混淆了「參考」這個詞的兩個不同含義(很多人)。

「傳遞引用」是編程領域的術語。也就是說,它有一個特定的含義:將一個變量的變量傳遞給一個函數,以便該函數可以觸及並更改該變量的內容。 JavaScript沒有傳遞引用。

你在你的問題要對付的是對象引用,裏面什麼都沒有做通,通過引用,它只是兩個概念包含「參考」(但相對於完全不同的東西的話)

對象引用是值。他們告訴JavaScript引擎對象在內存中的位置。

+1

這正是我所尋找的解釋。非常感謝你。 –

1

有趣的是,這與另一個最近的問題非常相似,儘管不是很愚蠢。

設置一個數據結構,試圖在不同的組件中使用這樣的引用來處理這個數據結構是一條黑暗的道路。如果你只是在討論一些代碼,這很有趣,但是在一個已部署的應用程序中,這很麻煩。

您最好創建一個結構,在該結構中,組件進行更改並將模型更改寫入該模型,然後模型廣播「髒數據」事件(或任何您想調用它的內容)包含註冊偵聽器(例如其他組件)正在偵聽的新數據。他們收到數據有效載荷並使用它。

對於希望按需提供數據的組件,您可以注入服務/訪問單例/您的框架執行的任何操作,並通過getter或某種簡單工廠函數訪問它。

您正在做的事情越來越多地讓對象發生變化。傳遞有問題的對象的不可變(或至少是複製的)版本更好。這樣,如果該對象發生變化,很容易找出在哪裏以及爲什麼。如果所有事情都有實際的參考(正如你上面看到的那樣,通常不會),對他們中的任何一個人的小改變都可能破壞你的早晨。

複製對象,如果你想知道,並不難。您可以複製對象只是這樣(假設它包含基本對象,基本類型等)

let myNewObj = Object.assign ({}, myOldObj); 
let myNewArr = [].concat (myOldArr); 

該對象是否具有類似的事情在他們的對象等數組,你可以深深這個老把戲複製:

let myFancyObjJSON = JSON.stringify (myFancyObj) 
let copy = JSON.parse (myFancyObjJSON) 

作品絕大多數的時間,除非你的類型是不典型(如地圖與符號的定義忽略了這些鍵的鍵)和其他一些未經常遇到的一天到一天的情況。

相信我,從經驗,重新思考你的結構(再次,除非這只是一個實驗)。

0

我已經擴大您的例子一點點地試圖澄清這是怎麼回事

var mainArray = [ 
 
    {a: 1}, 
 
    {b: 2} 
 
] 
 
var subArray = []; 
 
subArray.push(mainArray[ 0 ]); 
 

 
mainArray.splice(1, 1); // remove b from mainArray 
 

 
subArray[0].a = 5 // set a in subArray to 5 
 

 
console.log(mainArray, subArray); // [{a:5}] [{a:5}] a = 5 in both array (same object) 
 

 
var third = subArray; 
 

 
third[0].a = 15; 
 

 
console.log(mainArray, subArray, third); // [{a:15}] [{a:15}] [{a:15}] 
 
             // the same object a is changed everywhere 
 

 
third.splice(0, 1); 
 

 
console.log(mainArray, subArray, third); // [{a:15}] [] [] 
 
             // mainArray ---> object x ---> x[0] ---> a 
 
             // third and subArray ---> object y ---> y[0] ---> a 
 
             // there's no link between x and y directly