web-dev-qa-db-ja.com

JavaScript JSON.stringify関数が機能しない

JSオブジェクトをJSONに変換しようとしました。

JSON.stringify({a:1, toJSON: function(){}})

ネイティブJSON文字列化が期待どおりに機能していません。 JSON stringifyは、JSオブジェクトのtoJSON関数を内部的に実行します。ネイティブコードを次のように上書きしました。

// Adding try catch for non JSON support browsers.
try{
 _jsonStringify = JSON.stringify;
 JSON.stringify = function(object){
    var fnCopy = object.toJSON; 
    object.toJSON = undefined;
    var result =  _jsonStringify(object);
    object.toJSON = fnCopy;
    return result;      
 };
}catch(e){}

正常に動作しています。これを行う他のより良い方法はありますか?ネイティブコード実行toJSON入力オブジェクトの関数に特定の理由がありますか?

これは、JSON.stringifyが存在する場合、toJSON関数の戻り値が返されるためです( Source )。

例えば:

JSON.stringify({a:1, toJSON: function(){ return "a"; }});

戻ります:

"a"

この動作は MDNで説明されています です。これは、シリアル化の動作をカスタマイズできるようにするためです。たとえば、この例ではAnimalクラスのIDのみをシリアル化したいとします。私は次のことができました:

var Animal = function(id, name) {
    this.AnimalID = id;
    this.Name     = name;
};

Animal.prototype.toJSON = function() {
    return this.AnimalID;
};

var animals = [];

animals.Push(new Animal(1, "Giraffe"));
animals.Push(new Animal(2, "Kangaroo"));

JSON.stringify(animals); // Outputs [1,2]

この動作を望まない場合は、現在の方法が適切に機能します。ただし、JSON.stringifyの動作を上書きせず、メソッドに別の名前を付けることをお勧めします。外部ライブラリがオブジェクトでtoJSON関数を使用している可能性があり、予期しない結果が生じる可能性があります。

13
David Sherret

ネイティブの理由JSON.stringifyが機能しないのは、関数を文字列化できないためです。唯一の関数toJSONを未定義に設定すると、JSON.stringifyは適切な値を返します。詳細については、この質問を参照してください: JSON.stringify function

関数を完全に削除する場合は、次のようにします。

JSON.stringify(object, function(key, value) {
  if (typeof value === "function") {
    return undefined;
  }
  return value;
});
0
soktinpk