こんにちは!フロントエンドの最前線でコードを書き続けていると、ふと初心者の頃に「なんで自分の書いたコードが意図せず動いちゃうんだろう?」と夜も眠れなかった夜を思い出します。
JavaScriptを学び始めると、誰もが一度は「あれ?変数の値を書き換えたはずなのに、元の方まで変わってる!?」という魔法のような(そして悪夢のような)現象に遭遇します。
今日は、そんなJavaScriptの核心であり、最大の「罠」でもあるオブジェクトの参照渡しについて、専門用語を捨てて、身近な例え話で攻略していきましょう。
—
1. プリミティブとオブジェクト:魔法の箱と実物の鍵
まず、JavaScriptのデータ型は大きく分けて2種類あります。
- プリミティブ型(数値や文字列など):これは「実物」そのものです。
- オブジェクト型(配列や連想配列など):これは「実物」ではなく、「その場所を指し示す鍵」です。
プリミティブ型は「コピーされたメモ」
あなたが友達に「今の貯金額は1000円だよ」とメモを渡すとします。友達がそのメモを見て「いや、俺は2000円だと思う!」と言って自分のメモを書き換えても、あなたの手元のメモ(1000円)は変わりませんよね。これがプリミティブ型の挙動です。
オブジェクト型は「貸金庫の鍵」
一方でオブジェクトは「貸金庫の鍵」です。あなたが友達に「この金庫の鍵をあげる」と言って鍵を渡したとします。友達がその鍵を使って金庫を開け、中身を「1000円」から「5000円」に書き換えたらどうなるでしょう?
あなたが後から同じ金庫を開けても、中身は「5000円」になっていますよね。鍵は2つあっても、指している金庫は同じだからです。
—
2. コードで見てみる:なぜ「元」が変わるのか?
百聞は一見に如かず。実際にコードを書いて確認してみましょう。まずは「えっ、嘘でしょ?」となる挙動からです。
// 1. オブジェクト(鍵)を定義します
let myBag = { item: “りんご” };
// 2. myBagを別の変数に代入(鍵をコピーして渡した状態)
let yourBag = myBag;
// 3. yourBagの中身を書き換えてみる
yourBag.item = “みかん”;
// 4. myBagの中身を確認してみよう
console.log(myBag.item);
// 驚きの結果: “みかん” になっています!
// myBagを直接いじっていないのに、連鎖して変わってしまいました。
これが、JavaScriptが「参照」を扱っているという証拠です。`myBag`も`yourBag`も、メモリという大きな倉庫の中にある「同じ金庫」を指し示しているに過ぎないのです。
—
3. 「大丈夫、対策はあるよ!」
「じゃあ、オブジェクトを扱うときは常に破壊の恐怖と戦わなきゃいけないの?」と不安になりますよね。安心してください。現代のJavaScriptには、この「参照の呪縛」を解く便利な魔法が用意されています。
魔法の呪文:スプレッド演算子 (`…`)
「鍵を渡すのではなく、金庫の中身を全部取り出して、新しい金庫に詰め替える」という方法です。
let myBag = { item: “りんご” };
// …(スプレッド演算子)を使って、中身をバラして新しいオブジェクトに入れる
let yourBag = { …myBag };
// これでyourBagは「別の金庫」になりました
yourBag.item = “みかん”;
console.log(myBag.item); // “りんご” (無事!)
console.log(yourBag.item); // “みかん” (書き換わった!)
このように、新しい入れ物を作って中身をコピーしてしまえば、元のデータには一切影響を与えません。実務ではこの「不変性(イミュータブル)」を保つ書き方が、バグのない堅牢なコードを作るための黄金律とされています。
—
最後に:つまずくのは「理解している証拠」
JavaScriptの参照渡しで悩むのは、あなたがプログラムの「メモリの動き」まで想像できている証拠です。これは立派なエンジニアへの第一歩ですよ。
最初は「またやっちゃった!」と落ち込むこともあるかもしれません。でも大丈夫。そんな時は「あ、これ今、鍵を渡して共有しちゃってるな」と頭の中で貸金庫のイメージを浮かべてみてください。
プログラミングは、こうして一つずつ「見えない仕組み」を自分の手で確かめていく作業です。焦らず、少しずつ楽しみながら、この魔法の仕組みを自分の武器にしていきましょうね!
何か分からないことがあれば、いつでもまた聞いてください。あなたのコードが、今日も明日も軽やかに動くことを応援しています。

コメント