「ImJson」とビルトインの「JSON」の違い

はじめに

こんにちは。開発部のK.Sです。

今回はintra-martで利用できる「ImJson」とビルトインの「JSON」の違いについてです。

JSON (JavaScript Object Notation)とは、軽量のデータ交換フォーマットで、

ImJsonは、intra-martで利用できるJSON操作用のライブラリです。

業務で使用した際に気付いた両者の違いについていくつか紹介します。

JSON文字列変換時の型情報

   var obj = {
        name: "さとし",
        age: 25
    };
    var jsonWithType = ImJson.toJSONString(obj, true);
    var json = JSON.stringify(obj);
    Debug.print("ImJson: " + "\n"+ jsonWithType);
    Debug.print("ビルトインJSON: " + "\n"+ json);
ImJson:
 /* Object */
{
    /* String */
    "name" : "さとし",

    /* Number */
    "age" : 25
}


ビルトインJSON: 
{
    "name": "さとし",
    "age": 25
}

上記のようにImJsonでは、型情報がコメント形式で明示されるため、デバッグ時に非常に分かりやすいのが特長です。

一方で、ビルトインのJSON.stringifyでは、純粋なJSON形式が出力され、型情報は保持されません。

ただ、ImJsonではdebugFlgがtrueかfalseかの分岐がある分、ビルトインのJSONに比べ、多少負荷が大きくなる可能性があります。

そのため、デバッグ性を重視するならImJson、パフォーマンスを重視する環境ではビルトインJSONが適しているといえます。

日付型の変換

日付型の取り扱いにも明確な違いがあります。

   var date = new Date("2000/01/01")
    var obj = {
        birthDate: date
    };
    var jsonWithType = ImJson.toJSONString(obj, true); 
    var json = JSON.stringify(obj);
    Debug.print("日付: " + "\n" +date) 
    Debug.print("ImJson: " + "\n" + jsonWithType);
    Debug.print("ビルトインJSON: " + "\n" + json);
日付:
Sat Jan 01 2000 00:00:00 GMT+0900 (JST)

ImJson: 
/* Object */
{
    /* Date (Sat Jan 01 2000 00:00:00 GMT+0900 (JST)) */
    "birthDate" : new Date(946652400000)
}

ビルトインJSON:  
{
 "birthDate": "1999-12-31T15:00:00.000Z"
}

上記のようにImJsonでは、日付がDate型のまま出力され、JST(日本時間)で表示されます。

一方、ビルトインJSONではISO形式の文字列(UTC)として出力され、タイムゾーンによる日時のずれが生じます。

また、下記の様にビルトインJSONで一度文字列化した日付をJSON.parseで再パースしても、

元のDate型には戻らず、単なる文字列として扱われてしまいます。

   var date = new Date("2000/01/01")
    var obj = {
        birthDate: date
    };
    var json = JSON.stringify(obj);
    var parseJson = JSON.parse(json)
    Debug.print("元のオブジェクト: ")
    Debug.console(obj)
    Debug.print("再パース後のオブジェクト: ")
    Debug.console(parseJson)
元のオブジェクト:
/* Object */
{
    /* Date (Sat Jan 01 2000 00:00:00 GMT+0900 (JST)) */
    "birthDate" : new Date(946652400000)
}

再パース後のオブジェクト:
/* Object */
{
    /* String */
    "birthDate" : "1999-12-31T15:00:00.000Z"
}

JSONでDate型を取り扱う際には、日時の正確性や型の状態等を正確に把握しておくことが重要です。

対応の型

例えば、BigDecimal型を扱う例です。

   var obj = {
        value: new BigDecimal("123.45")
    };
    var jsonWithType = ImJson.toJSONString(obj, true);
    var json = JSON.stringify(obj);
    Debug.print("ImJson: " + jsonWithType);
    Debug.print("ビルトインJSON: " + json);
ImJson:
/* Object */
{
    /* BigDecimal */
    "value" : "123.45"
}"


"ビルトインJSON:
 {"value":{"plainString":"123.45"}}"

上記のようにImJsonでは、BigDecimal型がそのまま出力されます。

しかしビルトインJSONでは、BigDecimalがサポートされていないため、

内部的にはオブジェクトとして処理され、型情報が失われてしまいます。

他にもBigInteger型やFunction型等ImJsonでは対応していても、

ビルトインJSONでは対応していない型があるので注意が必要です。

まとめ

ImJsonとビルトインJSONの主な違いを整理すると、以下のようになります。

・ImJsonは型情報をコメント形式で出力できるため、デバッグに適している。

・ビルトインJSONはシンプルで高速だが、型情報が失われ、特に日付型ではUTCへの変換や再変換の手間が発生する。

・特殊なデータ型(BigDecimalなど)をそのまま扱いたい場合は、ImJsonの方が適している。

業務でJSONを扱う際には、単なるデータ変換だけでなく、

型の保持や日付の精度保持の仕方を考えることが重要です。

用途や目的に応じて、ImJsonとビルトインJSONをうまく使い分けていきましょう。

【参考】
intra-mart Accel Platform SSJS API Documentation

JSON.stringify() - JavaScript | MDN