2017-04-26 16 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 ]); 

...何がメモリ内に持っていることはビットのようになります。mainArraysubArray間の接続が全く存在しないこと

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

注意。両方とも、同じ値を持っています(someObjectの値でもあり、3つの場所すべてに同じオブジェクトのオブジェクト参照があります)。 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には何の効果もありません。


私はより良いスプライスに関連して参考作品に渡す方法を理解しようとしています。

「参照」という言葉には2つの異なる意味が混乱しています(多くの人が行います)。

「参照渡し」は、プログラミングの術語です。つまり、具体的な意味を持っています。への参照を変数に渡すことで、関数はその変数の内容を手に入れて変更することができます。 JavaScriptには参照渡しがありません。

オブジェクト参照は、参照渡しとは関係ありません。両方のコンセプトには「参照」という単語が含まれています(ただし、完全に異なるもの)

オブジェクト参照は値です。オブジェクトはメモリ内にあるJavaScriptエンジンに伝えられます。

+1

これは私が探していた正確な説明です。どうもありがとうございました。 –

1

面白いこれは別の最近の質問と非常によく似ています。

ディスクリートコンポーネント間でこのような参照を使用しようとするデータ構造を設定することは暗いパスです。興味深いのは、いくつかのコードでうっとりしているだけですが、配備されたアプリではこれは問題です。

変更を加えるコンポーネントによってモデルへの変更がそのモデルに書き込まれ、モデルが「ダーティデータ」イベント(またはそれを呼び出したいもの)をブロードキャストする構造を作成するほうがはるかに優れています。登録されたリスナー(例えば、他のコンポーネント)がリッスンしている新しいデータが含まれています。データペイロードを受信して​​使用します。

オンデマンドでデータを必要とするコンポーネントの場合、フレームワークが行うシングルトン/サービスに注入/アクセスし、ゲッターやシンプルなファクトリ関数を使用してアクセスします。

オブジェクトを突然変異させることは、あなたのやり方がますます激怒しています。問題のオブジェクトの不変(または少なくともコピーされた)バージョンを渡す方が良いでしょう。この方法では、そのオブジェクトが変更された場合は、場所と理由を簡単に見つけることができます。すべてが実際に動作する参照を持っている場合(そして、上に見られるように、それはしばしばありません)、それらのいずれかへの小さな変更はあなたの朝を壊すことができます。

不思議に思えば、オブジェクトをコピーするのは難しくありません。あなたは、単にオブジェクトをこのようにコピーすることができ、そのオブジェクトは、それらの中のオブジェクトなどとの配列のようなものを持っている場合

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

関連する問題