JavaScriptの共有渡しについて
少ししたら忘れてしまいそうなので、忘れないうちに自分なりにまとめておきます。JS初心者にとって少し混乱する内容だと思います。頑張って理解しましょう!
コードで説明
memoryは環境変数として宣言しているとします。これはメモリ内を模したオブジェクトだと思ってくれて大丈夫です。
/**
* 初期のメモリ構造
* memory
* {
* a: undefined,
* b: undefined
* }
* これから使うa, bという値はわかりやすくするために入れてあります。本来は何もありません
*/
const a = [1, 2, 3, 4, 5];
// memory内に新しい値を追加し、[1, 2, 3, 4, 5]を代入、その座標をaに代入する。
// ここではmemory[value]とする
/**
* この時点でのmemoryの構造
* memory
* {
* value: [1, 2, 3, 4, 5],
* a: memory[value],
* b: undefined
* }
*/
const b = a;
// 変数aに代入されてるmemory[value]の座標を変数bに代入する。値(value)はコピーされない。
/**
* memory
* {
* value: [1, 2, 3, 4, 5],
* a: memory[value],
* b: memory[value]
* }
*/
modifyArray(a);
// 変数aに代入されているmemory[value]の座標を関数に渡す。
/**
* この時点でのmemoryの構造
* memory
* {
* value: [1, 2, 3, 4, 5, 100],
* a: memory[value],
* b: memory[value]
* }
*/
function modifyArray(array) {
// ここで新しく関数用の変数であるarrayをメモリ内に宣言し、渡された値を代入する
// この関数に渡されたのはmemory[a]だが、座標はmemory[value]を指しているため、
// (memory[array] = memory[a]) == (memory[array] = memory[value])となる。
array.push(100);
// ここで実行されているのはmemory[array].push(100)であり、
// memory[array]の値はmemory[value]のため、memory[value].push(100)となり、
// memory[value]に100が追加される。
/**
* この時点でのmemoryの構造
* memory
* {
* value: [1, 2, 3, 4, 5, 100],
* a: memory[value],
* b: memory[value],
* array: memory[value]
* }
*/
/**
* ここでarray = [1, 2, 3]のような値の再代入を行った場合は
* memory
* {
* value: [1, 2, 3, 4, 5, 100],
* newValue: [1, 2, 3],
* a: memory[value],
* b: memory[value],
* array: memory[newValue]
* }
* このようにメモリ内に新しい値(ここではnewValueとする)が追加され、
* 関数内のarray(memory[array])の参照先がmemory[newValue]に変わり、
* arrayの中身を再代入後から編集してもmemory[newValue]の値が編集されるだけなので
* 元のmemory[value]には何も影響がありません。
*/
}
console.log(a); // memory[a]の値を表示(memory[value]: [1, 2, 3, 4, 5, 100])
console.log(b); // memory[b]の値を表示(memory[value]: [1, 2, 3, 4, 5, 100])
/**
* この時点でのmemoryの構造
* memory
* {
* value: [1, 2, 3, 4, 5, 100],
* a: memory[value],
* b: memory[value],
* }
* JavaScriptは、到達不可になった値はメモリから自動的に削除される機能(通称: GC)があるので、
* メモリ内のarrayという値は削除されます。
* GCはガベージ・コレクションの略です。
*/
まとめ
共有渡しとは "メモリの座標を渡すだけ" っていうシンプルな仕組みです。配列やオブジェクトを共有するというそのままの意味なのですが、コードを脳死で書いているとこのような仕組みを忘れて「なんだこれ!?なんか値が変化してる!?」となりそうなので、一応頭の中に入れておきましょう。ちなみにこのコードの中身が100%合っているという保証はないですが、大体このような感じだと思ってくれれば大丈夫だと思います。