3秒でわかる
それ以上は分解できない基本のデータ型。数値や文字列などがあたり、代入したときや比較したときのふるまいがオブジェクトと異なります。
もう少し詳しく
どういうものか
プリミティブは、言語が最初から用意している最小単位のデータ型です。JavaScript では string、number、boolean、null、undefined、symbol、bigint の 7 つ、Java では int、long、double、boolean、char などがこれにあたります。
対になるのがオブジェクトや参照型で、複数の値をまとめて持てるものです。配列、辞書、クラスのインスタンスはこちら側です。
なぜ必要か
違いが表面化するのは代入と比較のときです。プリミティブは値そのものが複製されるため、コピーした後で片方を変えてももう片方に影響しません。オブジェクトは場所を指す情報だけが複製されるので、コピー先を変えると元も変わります。
let a = 10;
let b = a;
b = 20;
console.log(a); // 10 のまま
let x = { n: 10 };
let y = x;
y.n = 20;
console.log(x.n); // 20 に変わる意図しない書き換えの原因がここに集中するため、区別を知らないままだと原因不明のバグとして残ります。
具体例
比較の挙動も違います。
console.log("abc" === "abc"); // true 中身で比べる
console.log([1, 2] === [1, 2]); // false 別物として扱う
console.log(<a href="/glossary/json-stringify" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">JSON.stringify</a>([1,2]) === JSON.stringify([1,2])); // trueJava でも同じ区別があります。
int a = 128, b = 128;
System.out.println(a == b); // true
Integer c = 128, d = 128;
System.out.println(c == d); // false 参照の比較になる
System.out.println(c.equals(d)); // true 中身の比較つまずきやすいところ
JavaScript では "abc".length のようにプリミティブへメソッドを呼べるため、オブジェクトだと勘違いしやすいです。実際は一時的にラッパーオブジェクトへ包んで呼び、直後に捨てています。だから "abc".foo = 1 と書いても何も残りません。
Java の Integer と int の混在も同じ落とし穴です。参照型の Integer を == で比べると、小さい値ではキャッシュのおかげでたまたま true になり、大きい値で false になります。値の比較は equals を使います。
typeof null が "object" を返すのは JavaScript の古い仕様上の不具合で、null はプリミティブです。
覚え方
「箱の中身を渡すのがプリミティブ、箱の住所を渡すのが参照型」です。