Strict Equality(厳密等価)とは?JavaScriptの===演算子を完全解説
JavaScriptを学習していると、必ず遭遇するのが「==」と「===」という2つの比較演算子です。特に「===」は「strict equality(厳密等価)」と呼ばれ、JavaScriptのバグを防ぐために非常に重要な概念です。この記事では、strict equalityの仕組みから実践的な使い方まで、初心者でもわかりやすく解説します。
目次
- Strict Equality(厳密等価)とは
- ==と===の違い
- 原因の説明:なぜStrict Equalityが必要か
- 解決手順
- 実践的なコード例
- よくある間違い
- まとめ
Strict Equality(厳密等価)とは
Strict Equality(厳密等価)とは、JavaScriptにおいて「===」演算子を使用して、2つの値が「完全に同じ」かどうかを判定する概念です。「完全に同じ」とは、値だけでなくデータ型も一致していることを意味します。
例えば:
- 数字の「5」と文字列の「”5″」は異なる(データ型が違う)
- 数字の「5」と数字の「5」は同じ(値もデータ型も同じ)
==と===の違い
JavaScriptには2つの等価演算子があります:
==(通常等価):値が等しいかどうかだけを比較。データ型の違いは自動的に変換される
===(厳密等価):値とデータ型の両方が等しいかどうかを比較。データ型の変換は行われない
具体例を見てみましょう:
// ==の場合(通常等価)
5 == \"5\" // true(値が同じなので)
0 == false // true(値が同じなので)
null == undefined // true
// ===の場合(厳密等価)
5 === \"5\" // false(データ型が異なる)
0 === false // false(データ型が異なる)
null === undefined // false(異なる型)
5 === 5 // true(値もデータ型も同じ)
原因の説明:なぜStrict Equalityが必要か
予期しない型変換によるバグ
JavaScriptの==演算子は「型強制(type coercion)」という機能を持っています。これにより、異なるデータ型の値を自動的に同じ型に変換して比較します。これは非常に危険で、多くのバグの原因となります。
// 危険な例
let user_input = \"0\"; // ユーザーが入力した値(文字列)
let system_value = 0; // システムの値(数字)
if (user_input == system_value) {
console.log(\"同じです\"); // これが実行される!
}
// しかし実際には異なるデータ型です
if (user_input === system_value) {
console.log(\"同じです\"); // これは実行されない
}
==の予測不可能な挙動
==演算子の型強制ルールは複雑で、非常に予測しにくいものです。次の例を見てください:
// 意外な結果
\"\" == 0 // true
\"\" == false // true
0 == false // true
\"0\" == false // true
null == 0 // false
undefined == 0 // false
// これらの結果は暗記する必要があり、バグの温床になります
解決手順
ステップ1:===を使う習慣を身につける
JavaScriptの比較には常に===を使うことを基本ルールにしてください。==を使う場面はほぼありません。
ステップ2:既存コードの==を===に置き換える
既に書いてあるコードがあれば、==を===に置き換えましょう。ほとんどの場合、コードの動作は変わりません。
ステップ3:リンターを設定する
ESLintなどのリンターツールを使用して、==を使った場合は自動的に警告が出るように設定します。これにより、うっかりした==の使用を防ぐことができます。
// .eslintrc.jsonの例
{
\"rules\": {
\"eqeqeq\": [\"error\", \"always\"]
}
}
実践的なコード例
例1:フォーム入力の検証
// ❌ 間違った例(==を使用)
function checkAge(input) {
if (input == 18) { // 文字列の\"18\"もtrueになる
console.log(\"成人です\");
}
}
checkAge(\"18\"); // \"成人です\"と表示(意図しない結果)
// ✅ 正しい例(===を使用)
function checkAge(input) {
if (input === 18) { // 数字の18のみtrueになる
console.log(\"成人です\");
}
}
checkAge(\"18\"); // 何も表示されない(期待通り)
checkAge(18); // \"成人です\"と表示
例2:データベースの値との比較
// ❌ 間違った例
const userData = {
id: \"123\",
status: \"active\"
};
if (userData.id == 123) {
console.log(\"ユーザーが見つかりました\"); // 実行される
}
// ✅ 正しい例
if (userData.id === \"123\") {
console.log(\"ユーザーが見つかりました\"); // 実行される
}
if (userData.id === 123) {
console.log(\"これは実行されません\");
}
例3:Boolean値との比較
// ❌ 間違った例
let isLoggedIn = \"true\"; // 文字列
if (isLoggedIn == true) {
console.log(\"ログイン状態です\"); // 実行されない場合もある
}
// ✅ 正しい例1:===を使う
if (isLoggedIn === true) {
console.log(\"ログイン状態です\"); // 確実に実行されない
}
// ✅ 正しい例2:Boolean値に変換してから使う
if (Boolean(isLoggedIn) === true) {
console.log(\"ログイン状態です\"); // 実行される
}
// ✅ 正しい例3:シンプルに書く
if (isLoggedIn) {
console.log(\"値が存在します\");
}
例4:null/undefinedの判定
let value = null;
// ❌ 間違った例(==を使用)
if (value == undefined) {
console.log(\"nullまたはundefinedです\"); // 実行される
}
// ✅ 正しい例1(null専用)
if (value === null) {
console.log(\"nullです\"); // 実行される
}
// ✅ 正しい例2(undefined専用)
if (value === undefined) {
console.log(\"undefinedです\");
}
// ✅ 正しい例3(どちらかでもいい場合)
if (value == null) { // この場合だけ==を使ってもいい
console.log(\"nullまたはundefinedです\");
}
例5:配列や オブジェクトの比較
// オブジェクトと配列は参照型なので===でも注意が必要
const obj1 = { name: \"Taro\" };
const obj2 = { name: \"Taro\" };
const obj3 = obj1;
console.log(obj1 == obj2); // false(異なるオブジェクト)
console.log(obj1 === obj2); // false(同じ理由)
console.log(obj1 === obj3); // true(同じ参照)
// 値が同じか確認したい場合
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true
よくある間違い
間違い1:「==の方が柔軟だから使える」という勘違い
初心者の中には、「==は型変換してくれるから便利」と考える人がいます。これは大きな誤解です。予測不可能な型変換はバグを生むだけです。
// これらの結果を全て暗記できますか?
console.log(\"0\" == 0); // true
console.log(\"\" == 0); // true
console.log(\"\" == false); // true
console.log([] == false); // true
console.log([] == \"\"); // true
console.log([0] == 0); // true
console.log([0] == \"0\"); // true
// ===を使えば、こんなことで悩む必要もありません
間違い2:「===なら全てのケースで安全」という勘違い
===を使えば完璧ですが、参照型(オブジェクトと配列)の場合は異なる注意が必要です:
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
console.log(arr1 === arr2); // false(異なる参照)
console.log(arr1 === arr1); // true(同じ参照)
// 値が同じかどうかを確認したい場合
console.log(arr1.join() === arr2.join()); // true
console.log(JSON.stringify(arr1) === JSON.stringify(arr2)); // true
間違い3:条件文でのデータ型チェックを忘れる
// ❌ 間違った例
function processInput(num) {
if (num === 0) {
console.log(\"ゼロです\");
}
}
processInput(\"0\"); // 何も表示されない(予期した結果)
processInput(null); // 何も表示されない(予期した結果)
// しかし、実際には型チェックが必要な場合もあります
function processNumber(num) {
if (typeof num !== \"number\") {
throw new Error(\"数字を入力してください\");
}
if (num === 0) {
console.log(\"ゼロです\");
}
}
間違い4:NaNの比較
// NaN(Not a Number)は特殊な値です
console.log(NaN === NaN); // false(NaN自体と等しくない)
console.log(NaN == NaN); // false(これも同じ)
// NaNを判定する正しい方法
const value = NaN;
console.log(Number.isNaN(value)); // true
console.log(isNaN(value)); // true(こちらは型強制される)
// 間違った判定
console.log(value === NaN); // false(使ってはいけない)
まとめ
Strict Equality(===)は、JavaScriptを安全に書くための必須スキルです。以下のポイントを覚えておきましょう:
重要なポイント
- 常に===を使う:==を使う理由はほぼありません
- データ型を意識する:JavaScriptは動的型言語ですが、型チェックは重要です
- 予測可能なコードを書く:型強制による予期しない挙動を避けます
- リンターを使う:ESLintで==の使用を自動的に防ぎます
- テストを書く:比較ロジックは必ずテストしましょう
実践的なチェックリスト
- [ ] プロジェクトのESLintで==を禁止に設定したか
- [ ] 既存コードの==を===に置き換えたか
- [ ] 参照型の比較方法を理解したか
- [ ] NaN、null、undefinedの判定方法を確認したか
- [ ] ユーザー入力の比較では常に===を使っているか
JavaScriptを学習する過程で、==と===の違いを理解することは、バグのない安全なコードを書くための基礎となります。この記事で紹介した例を実際に試してみて、Strict Equalityの重要性を体感してください。

