teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

平易な解説に書き換え

2018/02/07 02:35

投稿

miyabi-sun
miyabi-sun

スコア21465

answer CHANGED
@@ -7,13 +7,15 @@
7
7
  console.log(a === [100]); // false <- !?!?!?
8
8
  ```
9
9
 
10
- JavaScriptの世界ではArrayやObject等は生成時に`唯一の目に見えないID(以下ユニークID)`が割り振られて管理されています。
10
+ JavaScriptの世界ではArrayやObject等は生成時に`唯一の目に見えないID(以下ユニークID)`が与えられます。
11
+ ユニークIDの実体はオブジェクトが格納されているメモリ空間上のアドレスです。
11
- ユニークIDが一致している限り同じメモリ空間上に出来たただ一つオブジェトを参照している考えてください。
12
+ `var a = [100]`には配列実体そのものではなく、メモリ空間上のアドレス、つまりユニーIDいう特殊な数値が代入れてます
12
13
 
13
- `[100] === [100]`は`[100]`という配列を2個生成して、
14
+ `[100] === [100]`は`[100]`という配列を2個生成して、それぞれにユニークIDを割り振ります。
15
+ オブジェクト同士の比較演算では、このユニークID同士のみを比較します。
14
- ユニークID同士を比較する結果が`false`になるのです。
16
+ ユニークID以外は完全に一致する2つの`[100]`ですがユニークID異なる為に`false`になるのです。
15
17
 
16
- 今回説明している「ユニークIDという単語一般的な名ではありません、`メモリ空間のアドレス`がより正しい呼び名で
18
+ ※ユニークIDと連呼してますが、これ説明し易いから呼んでいるだけで正式な名ではありません。この回答文以外ではメモリ空間のアドレス等の呼んで下さい。
17
19
 
18
20
  ---
19
21
 
@@ -27,12 +29,14 @@
27
29
 
28
30
  var c = b;
29
31
  c[0] = 3;
30
- console.log(b, c); // [3], [3] <- !?!?!?
32
+ console.log(a, b, c); // [2], [3], [3] <- !?!?!?
31
33
  ```
32
34
 
33
35
  配列やオブジェクトの値を操作する場合、ユニークIDに従ってメモリ空間上にある値を直接更新します。
34
36
  その結果、上記のコードでは`c[0]`の変更の影響が`b[0]`に出ています。
35
37
 
38
+ ちなみにaとbは別々に配列を作っていますので相互不干渉です。
39
+
36
40
  ---
37
41
 
38
42
  この仕様、一部のケースではとても困ります。
@@ -56,5 +60,12 @@
56
60
  console.log(a, b); // [1, 2, 3, 4, 5], [10, 2, 3, 4, 5]
57
61
  ```
58
62
 
63
+ aとbは別々の配列を作る宣言をしていますので、ユニークIDは別個です。
59
- も様々な手法がありますが、
64
+ その後a配列の要素を一つずつbコピーしていますが、
65
+ aとbは既に切り離されていますし、a配列の要素は全て数値なのでユニークIDのコピーは発生しません。
66
+
67
+ bはaのクローンを作る事に成功したのです。
68
+ 従って、a配列には影響を与えずに`b[0] = 10`と意図通りの操作を行う事に成功しています。
69
+
70
+ この手法は「シャローコピー」、「ディープコピー」、「クローン」などといった用語で説明されています。
60
- もし必要になればシャローコピーやディープコピーといった単語で検索てみてください。
71
+ もし必要になった際には、これらのワードで検索を掛けてみてください。