【JavaScript】オブジェクトの抽象比較の結果と仕組み

更新日:2024/02/19

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

 

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

抽象比較を行う前にオブジェクトは、数値や文字列などのプリミティブに変換されます。
変換結果は、デフォルトでは次のようになります。

"[object Object]"

つまり次の比較は、

({}) < 1

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

"[object Object]" < 1

数値文字列以外の文字と数値との比較は、大小関係なく false になります。

オブジェクトとオブジェクトの比較なら、次のような流れで比較されます。

①({}) < ({}) "[object Object]" < "[object Object]" false
②({}) <= ({}) "[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/19

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

スポンサーリンク

記事の内容について

null

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

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

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

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

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

 

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