技術とかの雑なToday I Learnedメモ

JavaScriptはそもそも参照渡しと値渡しなんかしてないよという記事を読んだ

JavaScriptはそもそも参照渡しと値渡しなんかしてないよという記事を読んだ

【JavaScript】 参照渡し?値渡し?これで悩む必要がなくなる!かも

ここらへんで結構こんがらがっていたので整理。

整理というか、参照渡しと値渡しがあると思っていたんだけどどうやら違ったらしい。

> let hoge = { a: 10, b: 20 }
< undefined
> const func = (obj) => {
      obj = 20
  }
< undefined
> func(hoge)
< undefined
> hoge
< {a: 10, b: 20}

devtoolsのconsoleで記事内のコードと似たようなものを試してみた。

オブジェクトが参照渡しだった場合、funcに渡しているのはhogeの参照なのでhogeの値が変化するはずだから参照渡しではない、ということかな。

> let hoge = { a: 10, b: 20 }
< undefined
> const func = (obj) => {
      obj.a = 30
  }
< undefined
> func(hoge)
< undefined
> hoge
< {a: 30, b: 20}

もし値渡しだとした場合、funcの引数に渡されるのは参照ではなく値なので、hoge.aが30になってるということは値渡しではないよねという感じっぽい。

結局、変数 <=> 参照値 <=> データ(メモリ上)という構造があり、代入というのは変数に参照値を代入するということなんだと認識した。

で、プリミティブ型は上記の関係性だけでいけるけど、オブジェクトのプロパティも配列の要素も参照値を持てるので、参照値であるオブジェクトのプロパティが持つ参照値をいじると、そのオブジェクトの参照値を持つ変数の値は全部変わるということっぽい。

難しい……。

JavaScriptに参照渡し/値渡しなど存在しない - Qiita

変数に値を再代入すると"値の参照"が置き換わる」と「変数に変数を代入するとその変数に入ってる"値の参照"が入る」から考えれば、変数aに100を代入した時点で変数aが持っている参照が新たに作られた100に変わるだけで、もともと変数aが持ち、変数bに代入された10の参照が変わるわけではないです。

分かりやすかった。プリミティブ型の値は、参照値ではなく「値」なので、書いた時点で新しい参照値が作られると考えれば、値渡しのような挙動になっているということが分かる。

代入している対象は変数自体ではなく、その変数が持っている(参照の先にある)オブジェクトのプロパティです。つまり、「変数に値を再代入すると"値の参照"が置き換わる」が当てはまらず、2つの変数が同じオブジェクトを指しているままになり、ただ同じオブジェクトを操作してるだけになります。(プリミティブ値はプロパティ代入できないので逆のことはできないのですが)

オブジェクトのプロパティをいじるときは、プリミティブ型とは違って「既にある参照値の中身をいじる」という感じなので、その参照値を持っている変数の中身が全部入れ替わるということかな。

なんとな〜く分かったような分からないような。