【JavaScript】オブジェクトの抽象等値比較(==、!=)の結果と仕組み

更新日:2024/02/20

JavaScriptは、==、!= での比較を抽象等値比較と呼んでいます。
オブジェクトを抽象等値比較の対象とすることができますが、どのような結果になるのか資料があまりありません。
そこで、今回はオブジェクトの抽象等値比較の結果と仕組みについて解説します。

 

オブジェクトの抽象等値比較の結果

抽象等値比較は左右の型が同じなら、厳密比較されます。
つまりオブジェクト同士を抽象等値比較すると厳密比較され、同じオブジェクトのとき結果が true になります。

型が異なる時はオブジェクトは、数値や文字列などのプリミティブに変換されます。
変換結果は、デフォルトでは次のようになります。

"[object Object]"

つまり次の比較は、

({}) == 1

次のように置き換えられ、

"[object Object]" == 1

結果は false になります。

ちなみに、オブジェクトと"[object Object]"を比較すると、次のような流れでtrueになります。

({}) == "[object Object]" "[object Object]" == "[object Object]" true

 

オブジェクトのプリミティブ化の仕組み

オブジェクトのプリミティブ化は、次のメソッドを順番に存在するかどうか確認して、存在するなら実行します。
実行結果がオブジェクト以外なら、その値が変換後のプリミティブとなります。

  1. [Symbol.toPrimitive]("number")
  2. valueOf()
  3. toString()

オブジェクトはデフォルトでは、1.の[Symbol.toPrimitive]が存在しないので、実行されません。
2.のvalueOf()は、自分自身、つまりオブジェクトを返すので、プリミティブではありません。
3.のtoString()は"[object Object]"を返すので、この文字列が変換結果となります。

 

オブジェクトの抽象等値比較のカスタマイズ

オブジェクトと他の型との抽象比較結果は、仕組みで挙げたメソッドを追加することでカスタマイズできます。
今回は、[Symbol.toPrimitive]メソッドを追加してみます。

const obj = {
    num : 1000,
    [Symbol.toPrimitive]:function(hint){
        switch ( hint ){
            case "number": return this.num;
            case "string": return this.toString();
            default: return this.num;
        }
    }
};
console.log( obj == 1 ); // true

これで数値による比較ができるようになりました。
任意の文字列で比較するときは、case "number":で文字列を返します。
比較対象が文字列だからといって、case "string":の方を評価することは無いので注意が必要です。

更新日:2024/02/20

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。