【実務・中級編】 Object.is()メソッド – JavaScript実践ガイド

なぜ、いまさら「Object.is()」なのか? ― JavaScriptの「厳密」のその先へ

現場でコードレビューをしていると、`===`(厳密等価演算子)が最強の盾だと信じきっているエンジニアによく遭遇します。確かに、型まで含めて判定する`===`は9割のケースで期待通りに動く。しかし、JavaScriptという言語は、たまに我々の常識を嘲笑うような「境界線上の挙動」を突きつけてくるものです。

今日語りたいのは、そんなJavaScriptの深淵を覗くためのツール、`Object.is()`についてです。

「===」が陥る2つの罠

まず、`===`が持っている「たった2つの弱点」を理解しましょう。これを知らないと、特に数値計算やライブラリ開発時に痛い目を見ます。

1. NaNの不一致: `NaN === NaN` は `false` です。
2. 符号付きゼロの区別なし: `+0 === -0` は `true` です。

「NaNが自分自身と等しくない」というのは、JavaScriptの仕様(IEEE 754)に深く根ざした有名な話ですが、現場でこれに直面すると「えっ、値があるはずなのに判定が通らない…?」というデバッグ地獄の入り口になります。また、金融系やグラフ描画系の計算で、符号付きゼロ(`-0`)を厳密に扱う必要がある場合、`===`では太刀打ちできません。

そこで登場するのが、ES6で導入された `Object.is()` です。

Object.is() の正体:仕様の「最終防衛ライン」

`Object.is()` は、ブラウザのエンジンが「この2つの値は、メモリ上の表現も含めて完全に同一か?」を判定するための比較関数です。

`===` との比較表を見ると、その立ち位置が明確になります。

| 比較内容 | `===` | `Object.is()` |
| :— | :— | :— |
| `NaN` と `NaN` | `false` | `true` |
| `+0` と `-0` | `true` | `false` |
| その他 | 同じ | 同じ |

ブラウザの裏側では、`Object.is()` は「SameValueアルゴリズム」に基づいて動いています。これは「値が同じである」と人間が直感的に期待する挙動を、言語仕様レベルで強制的に定義したものです。

実務で「Object.is()」をどう使いこなすか

では、これをどこで使うべきか? 私が現場で推奨しているパターンを共有します。

1. NaNの安全なチェック

配列の要素から `NaN` を見つけたいとき、`indexOf` などを使うと失敗します。`Object.is` を組み合わせることで、意図通りに動作させることができます。

const data = [10, NaN, 20];

// indexOfはNaNを無視してしまうため、これでは見つからない
console.log(data.indexOf(NaN)); // -1

// findIndex と Object.is を使えば、正しくNaNのインデックスを取得できる
const index = data.findIndex(val => Object.is(val, NaN));
console.log(index); // 1

2. Reactの最適化(メモ化)の裏側

Reactの `memo` や `hooks` (`useMemo`, `useEffect` の依存配列比較)では、内部的にこの `Object.is` (に近い比較アルゴリズム)が使われています。もしあなたが自前でカスタムフックやレンダリング最適化を実装する際、値の変更を厳密に検知したいなら、`Object.is` は最も信頼できる判定基準になります。

// レンダリングをスキップするための判定ロジック例
function shouldUpdate(prevProps, nextProps) {
// オブジェクトの浅い比較だけでなく、特殊な数値判定もこれでカバー可能
return Object.is(prevProps.value, nextProps.value);
}

現場のエンジニアへ:使い分けの指針

ここまで読んで「これからは全部 `Object.is()` で比較しよう」と思ったとしたら、それは少し早計です。

  • 基本は `===` でOK: コードの可読性とパフォーマンスを考えれば、通常の比較は `===` で十分です。わざわざ `Object.is` を使う必要はありません。
  • 「計算の境界」で使う: `NaN` を扱う可能性がある、あるいは `+0 / -0` を厳密に区別する必要がある(例:数学的計算、WebGLのシェーダー連携など)といった、「特殊なドメイン」でのみ `Object.is` を引き抜くのがプロの采配です。

まとめ

JavaScriptの仕様は、ある意味で「歴史的な妥協の産物」です。`NaN` が自分と等しくないのも、ある種の歴史的背景があります。しかし、それを理解した上で適切な道具を選ぶのが、我々フロントエンド・アーキテクトの仕事です。

「なぜその比較を使っているのか?」と問われた時に、「`===` だと `NaN` を判定できないから、`Object.is` を使っているんだ」と即答できるエンジニアになってください。その一言が、あなたのコードを一段上のレベルへと引き上げます。

さあ、エディタを開いて、プロジェクト内の比較ロジックを見直してみましょう。思わぬところに「`NaN` の地雷」が埋まっているかもしれませんよ。

コメント

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