Strict Equality(厳密等価)とは?JavaScriptの===演算子を完全解説

未分類

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の重要性を体感してください。

タイトルとURLをコピーしました