- 結論から言うと、bの値への参照情報
- 参照渡しじゃんとなるけど、アドレスを渡しているかまで
言語仕様理解してないのであくまで「実値への参照情報」 - JavaScriptがそもそも高級よりでメモリとか関与してなさそうだから
渡してるのはアドレスな気がする。(これは自分の意見)
- 参照渡しじゃんとなるけど、アドレスを渡しているかまで
- 下記記事と主張は同じ。またソースの一部を引用させていただいています。
-
- プリミティブ値が値渡し、それ以外が参照渡しという意見(事実かも)を
見るが、JavaScriptに他言語のような値渡し、参照渡しを行う構文が
用意してないよう見受けられるため上記記事の認識のが自分はしっくりきた - (VB系列やC#には
Ref
,Val
みたいなこれは値渡しの
変数だよという構文がある)
- プリミティブ値が値渡し、それ以外が参照渡しという意見(事実かも)を
参照させていただいた記事内のソース+自分で手を加えたやつで
「実値への参照」が入る論を紐解いていくパターン1(プリミティブな値の代入)
var a = 10; var b = a; a = 100; console.log(a); //?? console.log(b); //??
a
は3ステップ目で100が代入されているので「100」が出力b
は2ステップ目でa(10への参照)
が代入されているので「10」が出力- イメージ図は下図
- パターン2(プリミティブでない値の代入)
var a = {val:10}; var b = a; a.val = 100; console.log(a); //?? console.log(b); //??
a
は1ステップ目でオブジェクトへの参照(object→val→10)までが入り、
3ステップ目でオブジェクト内の値val
の参照先が100に変更されるval
への参照はオブジェクトでラップされているため
そのオブジェクトを参照しているa
も「100」となる
b
はa
が持つオブジェクトへの参照が同じく入るので「100」が出力- イメージ図は下図(TODO:Objectも色分けした方がいい)
シャローコピー、ディープコピーはどうして起こるか
上記認識だと、ここのコピー問題もどうして起きるのかが説明しやすい
シャローコピー例
- 下記のような単純な代入だけでなく、
object.assing()
等の
オブジェクト操作系のメソッドでもシャローコピーとなる
- 下記のような単純な代入だけでなく、
let obj = {"A":1, "B":2, "C":3}; //単純な代入はシャローコピーとなる let objCopy = obj; //コピー先の要素を変更する objCopy['A'] = 4; console.log(JSON.stringify(obj)); // {"A":4,"B":2,"C":3} console.log(JSON.stringify(objCopy)); // {"A":4,"B":2,"C":3}
- パターン2と同様でコピー先にはコピー元の参照情報が入るので、
宣言したオブジェクトの変更が両方に影響する - イメージ図は下図
- ディープコピー例
- コピー時に参照情報が入らないように、コピー元を明示的に複製して、
複製したものを代入すればコピー元の参照は影響がなくなる
- コピー時に参照情報が入らないように、コピー元を明示的に複製して、
let obj = {"A":1, "B":2, "C":3}; //JSON変換→パースを行うことでオブジェクトを明示的に複製する let objCopy = JSON.parse(JSON.stringify(obj)); //コピー先の要素を変更する objCopy['A'] = 4; console.log(JSON.stringify(obj)); // {"A":1,"B":2,"C":3} console.log(JSON.stringify(objCopy)); // {"A":4,"B":2,"C":3}
objCopy
はJSON形式のテキストデータから新規作成されるため、
copy
への参照情報は入らない- 互いに別オブジェクトとして扱える
- イメージ図は下図
結論
- パターン1,2より
=
による代入は右辺の実値への参照情報
が入る認識がしっくりくる