JavaScript | ES6+ 文法:オブジェクト拡張 – Object.is

JavaScript JavaScript
スポンサーリンク

Object.is とは何か

Object.is は、「2つの値が“本当に”同じ値かどうか」を判定するための ES6 の比較関数です。
見た目は ===(厳密等価演算子)に似ていますが、NaN+0 / -0 の扱いだけが違う、これが一番のポイントです。

console.log(Object.is(1, 1));       // true
console.log(Object.is("a", "a"));   // true
console.log(Object.is({}, {}));     // false(別オブジェクト)
JavaScript

ほとんどの場合は === と同じ結果になりますが、「例外的な2ケース」を丁寧に扱いたいときObject.is が真価を発揮します。


=== とどこが違うのか(重要ポイントは 2つだけ)

NaN 同士の比較が true になる

=== では、NaN 同士の比較は false になります。

console.log(NaN === NaN);      // false
JavaScript

これは「NaN は“何にも等しくない”」という IEEE のルールに従っているためですが、
実務では「両方とも NaN なら“同じ”とみなしたい」ことが多いです。

Object.is は、ここを分かりやすくしてくれます。

console.log(Object.is(NaN, NaN));  // true
JavaScript

ここが重要です:
「NaN かどうかを判定したいなら、Number.isNaNObject.is(value, NaN) を使うと確実です。

const v = 0 / 0; // NaN

console.log(Number.isNaN(v));     // true
console.log(Object.is(v, NaN));   // true
JavaScript

+0 と -0 を区別する

=== では、+0-0 は同じとみなされます。

console.log(+0 === -0);      // true
JavaScript

しかし、数学的・低レベルな数値処理では「+0 と -0 を区別したい」ことがあります。
Object.is はここを区別します。

console.log(Object.is(+0, -0));  // false
console.log(Object.is(+0, +0));  // true
console.log(Object.is(-0, -0));  // true
JavaScript

ここが重要です:

  • ===:+0 と -0 は同じ
  • Object.is:+0 と -0 は違う値

普段のアプリ開発では +0 / -0 を意識することはほとんどありませんが、
内部的なライブラリ実装や数値処理では、この違いが意味を持つ場面があります。


それ以外は基本的に === と同じ

上の 2つ(NaN と +0/-0)以外では、Object.is=== の結果は同じです。

console.log(Object.is(1, 1));          // true
console.log(Object.is(1, "1"));        // false
console.log(Object.is("a", "a"));      // true
console.log(Object.is(true, true));    // true
console.log(Object.is(null, null));    // true
console.log(Object.is(undefined, undefined)); // true

const obj = {};
console.log(Object.is(obj, obj));      // true(同じ参照)
console.log(Object.is({}, {}));        // false(別オブジェクト)
JavaScript

つまり、普段は === を使い、NaN や +0/-0 を正確に扱いたいときにだけ Object.is を選ぶ、という使い分けになります。


どんな場面で使うのか(実務寄りのイメージ)

状態の変化を「本当に変わったか」で判定したいとき

例えば、「新しい値が前回と同じなら何もしない」「違うときだけ処理する」といったパターン。

function updateValue(prev, next) {
  if (Object.is(prev, next)) {
    console.log("変化なし");
    return prev;
  }
  console.log("変化あり:", prev, "→", next);
  return next;
}

updateValue(1, 1);       // 変化なし
updateValue(1, 2);       // 変化あり
updateValue(NaN, NaN);   // 変化なし(=== では判定しづらいケース)
JavaScript

NaN が絡む場合、=== だけでは「同じかどうか」を判定しにくいため、
Object.is を使うと「どんな値でも一貫した基準」で比較できます。

ライブラリ内部での「同値判定」として

React や一部のフレームワークでは、
「前回と同じ値かどうか」を見るために Object.is 相当のロジックが使われます。

このとき、+0/-0 の違いも含めて「完全に同じか」を判断したいので、
=== ではなく Object.is 互換の処理が採用されることがあります。

初心者としては、
「ライブラリの内部では、Object.is のような“より厳密な等価判定”が使われることがある」
くらいの理解で十分です。


Object.is の書き方と注意点

基本形

Object.is(値1, 値2);
JavaScript

両方の値が「同一」と見なされれば true、そうでなければ false です。

console.log(Object.is("a", "a"));   // true
console.log(Object.is("a", "b"));   // false
JavaScript

オブジェクトは「同じ参照かどうか」で比較される

=== と同様、オブジェクトは「中身」ではなく「参照(ポインタ)」が比較されます。

const obj1 = { x: 1 };
const obj2 = { x: 1 };
const obj3 = obj1;

console.log(Object.is(obj1, obj2)); // false(中身が同じでも別オブジェクト)
console.log(Object.is(obj1, obj3)); // true(同じものを指している)
JavaScript

ここが重要です:
Object.is は「オブジェクトの内容が同じかどうか」を判定するツールではない
という点を間違えないようにしてください。
(オブジェクトの「内容比較」は、別途ロジックやライブラリが必要になります。)


=== / == / Object.is のざっくり整理

初心者のうちに整理しておくと頭がすっきりするポイントです。

==(抽象等価演算子)

  • 型を“ゆるく”変換して比較する
  • 予想外の結果を生みやすいので、基本的に 使わないほうがいい
console.log(1 == "1");   // true
console.log(0 == false); // true
JavaScript

===(厳密等価演算子)

  • 型を変換せず、そのまま比較する
  • 日常的な「等しいかどうか」の判定は基本これ
console.log(1 === "1");   // false
console.log(1 === 1);     // true
console.log(NaN === NaN); // false(ここがちょっと直感的でない)
JavaScript

Object.is

  • 基本は === と同じ
  • ただし NaN を「自分自身と等しい」扱いにする
  • +0-0 を区別する
console.log(Object.is(1, 1));       // true
console.log(Object.is(1, "1"));     // false
console.log(Object.is(NaN, NaN));   // true
console.log(Object.is(+0, -0));     // false
JavaScript

ここが重要です:

  • 日常:=== を使う
  • NaN+0/-0 をきちんと扱いたい場面:Object.is を使う
  • == は原則封印してOK(どうしても必要な特殊ケース以外は使わない)

例題で理解を固める

// 1) NaN の判定
const v1 = 0 / 0;      // NaN
const v2 = Math.sqrt(-1); // NaN(ブラウザ環境など)

console.log(v1 === v2);             // false(比較にならない)
console.log(Object.is(v1, v2));     // true(どちらも NaN と判定)
console.log(Object.is(v1, NaN));    // true

// 2) +0 / -0 の違い
const pz = +0;
const nz = -0;

console.log(pz === nz);          // true
console.log(Object.is(pz, nz));  // false

// 3) 状態更新のときに使うイメージ
function setState(prevState, nextState) {
  if (Object.is(prevState, nextState)) {
    console.log("状態は変わっていないのでスキップ");
    return prevState;
  }
  console.log("状態更新:", prevState, "→", nextState);
  return nextState;
}

setState(1, 1);       // スキップ
setState(1, 2);       // 更新
setState(NaN, NaN);   // スキップ(NaN 同士は同じとみなされる)

// 4) オブジェクト参照の比較
const a = { x: 1 };
const b = { x: 1 };
const c = a;

console.log(Object.is(a, b)); // false(別オブジェクト)
console.log(Object.is(a, c)); // true(同じ参照)
JavaScript

まとめ

Object.is の核心は、
「ほぼ === と同じだが、NaN を自分自身と等しいとみなし、+0-0 を区別する“より厳密な等価判定”」
だということです。

普段は === を使い、
NaN をちゃんと扱いたい」「+0-0 を区別したい」「値の変化を“本当の意味で”チェックしたい」
といった場面で Object.is を選ぶ、という使い分けができれば十分です。

この違いを押さえておくと、
「なぜここだけ Object.is を使っているんだろう?」という他人のコードも、
自信を持って読み解けるようになります。

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