JavaScriptの仕様でオブジェクトは参照渡しというものがあります。
Reactのドキュメントを読んでいたところオブジェクトのコピーについて理解できてなかったのでこの際に理解を深めたいと思います。
JavaScripの参照渡しについて
JavaScriptでは、プリミティブ型の数値、文字列、真偽値、null、undefinedなどは値渡しですが、オブジェクト型の配列、連想配列、関数は参照渡しです。
なぜ参照渡しなのか?
JavaScriptのメモリ管理とパフォーマンスに考慮するためだそうです。
具体的には、プリミティブ型は値が直接保存されるため、その値をコピーする際には新しいメモリ領域を確保して値をコピーする必要があります。
一方、オブジェクト型は参照渡しなのオブジェクトが保存されているメモリ領域への参照をコピーすることでメモリ使用量は少なくなります。
オブジェクトのプロパティを変更した場合、その変更は参照を持っているすべての変数に反映されます。
オブジェクトのデータ量に応じて処理に負荷がかかるため値の変更に注意が必要です。
まとめると…
- 値渡しは、メモリ使用量が増えるが変更の際のパフォーマンスは良い
- 参照渡しは、メモリの使用量は減るが変更の際のパフォーマンスに注意が必要
小さなデータを扱う場合は値渡しの方が効率的、大きなデータの場合は値渡しの方が効率的。
そもそもJavaScriptに「参照渡し」は存在しない!?
この記事では「参照渡し」として諸所説明してきましたが…そもそもJavaScriptに「参照渡し」はないと知りました。
コメントでもいただいている通り、JavaScriptにおける「参照渡し」は参照の値渡しという表現が正しいようです。
参照渡しと参照の値渡しをコードで説明すると
let a = { value: 10 }
let b = a
a.value = 50
console.log(a) // { value: 50 }
console.log(b) // { value: 50 }
a
のvalue
を変更するとb
の値も連動して変化します。
これが参照渡しと言われる状態です。
ただ、下記のようにするとa
とb
の値がそれぞれ別のものになります。
let a = { value: 10 }
let b = a
a = { value: 50 }
console.log(a) // { value: 50 }
console.log(b) // { value: 10 }
参照渡しであればa
が置き換わるとb
も置き換わっているはずですが、JavaScriptの場合は別の値に置き換わってしまって連動しなくなります。
なのでJavaScriptの参照渡しと言われているものは、世間一般の参照渡しとは性質の異なるものです。
実際には「参照値」という「値」を「値渡し」しているため参照の値渡しと表現されるそうです。
参考の記事
まとめ
オブジェクトの特徴について考えたことはなかったですが、JavaScriptの仕様に詳しくなればコードを綺麗に書くことに繋がったり、デバッグの速度が上がったりするのではないかと思います。
とはいえ量が多いので、1つずつ深度を深めてJavaScriptへの理解を深めいたいと思います。