3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プリミティブと参照型の違いがわからないと、JavaScriptは一生バグる

Last updated at Posted at 2025-03-30

概要

JavaScriptのバグの多くは、「何が渡されて、何が変わったのか」が見えていないところから始まる。
その本質にあるのが、プリミティブ型(値を直接渡す)と参照型(実体の参照という値を渡す) の違いだ。

この理解が曖昧なままコードを書くと、オブジェクトが意図せず書き換わったり、配列が破壊されたりする。
意図しない副作用が“静かに”発生する、最も根深いバグ要因の一つである。

この記事では、プリミティブと参照型の本質的な違いを明確にし、実務でどう活かすかまでを徹底的に掘り下げる。

補足

※ 厳密には、JavaScriptはすべて「値渡し(pass by value)」です。
オブジェクトや配列は「参照を値として渡す」ため、関数内で状態が変化するように見えるだけです。
本記事では便宜上「参照渡し」と表現している箇所がありますが、正確には「同じ参照が渡っている」と読み替えてください。

対象環境

モダンブラウザ対応のJavaScript(ES6〜)  
Node.js含む全実行環境

そもそも「プリミティブ型」とは何か?

プリミティブ型(Primitive)は、値そのものを扱う型。

✅ 対象となる型:

string
number
boolean
null
undefined
symbol
bigint

特徴:

  • 値そのものを保持・渡す
  • 変更不可(イミュータブル)
  • コピーすれば完全に分離された値になる
let a = 'hello';
let b = a;
b = 'world';

console.log(a); // 'hello'(変更されていない)

ab完全に独立した値

「参照型」とは何か?

参照型(Reference)は、実体へのポインタを扱う型

✅ 対象となる型:

object
array
function

特徴:

  • 実体はヒープに格納され、変数はその参照(ポインタ) を持つ
  • コピーしても同じものを指している
  • 一方を変更するともう一方も変わる
let obj1 = { name: 'Alice' };
let obj2 = obj1;

obj2.name = 'Bob';

console.log(obj1.name); // 'Bob'(obj1 も書き換わっている)

→ これはobj1 と obj2 が同じ場所を見ているため

破壊的コードと非破壊的コードの差

// 破壊的(mutate)
const list = [1, 2, 3];
list.push(4); // 変更される

// 非破壊的(immutable)
const newList = [...list, 4]; // listは変わらず、新しい配列を返す

→ React / Vue / Redux など、状態管理が重要な設計では「非破壊」が必須
→ 参照型をそのまま操作すると、予期せぬ状態変化が発生する

関数渡しの落とし穴

function mutate(obj) {
  obj.value = 100;
}

const data = { value: 0 };
mutate(data);

console.log(data.value); // 100 ← 副作用が発生

→ 参照型を引数に渡すと、関数内で外部の状態を破壊できる

✅ 対策:構造をコピーして渡す

function safeMutate(obj) {
  const copy = { ...obj };
  copy.value = 100;
  return copy;
}

const result = safeMutate(data);
console.log(data.value);   // 0
console.log(result.value); // 100

→ 安全な状態変更には、ディープコピー or シャローコピー + 再代入が有効

比較の罠:プリミティブと参照型の ===

'hello' === 'hello'      // true
{} === {}                // false
[] === []                // false

参照型は“中身”ではなく“場所”が違えば false

実務Tips:参照型と付き合う4つの原則

  1. 引数でオブジェクトや配列を受け取る関数は、副作用を避ける
  2. 再利用される変数にはシャローコピー / ディープコピーを必ず検討
  3. 状態管理ではイミュータブルなパターン(スプレッド演算子など)を徹底
  4. 参照型を比較するときは、参照の一致か、値の比較かを意識する

結語

JavaScriptは「すべてがオブジェクト」という呪文のもと、プリミティブと参照型が曖昧に扱われがちだ。
だが、バグの原因の多くは、その構造の違いに起因する。

  • 値で渡されるのか
  • 参照でつながっているのか
  • それがどのスコープで共有されるのか

この3点を見極めることが、副作用のないロジックと保守性の高い設計を作る鍵になる。

コードを制御するとは、状態と記憶を理解することだ。
JavaScriptの型は、ただの仕様ではなく、「どこで何が変わるか」を読み解くためのレンズである。

3
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?