2

文字列としてシリアライズしたい JavaScript オブジェクトがあります。

key                     {...}       Object
    mandant             "00001"     String
    personalNummer      600235      Number

まず、戻り値が である JSON2 を使用しましたundefinedJSON3を使用すると、次TypeErrorの行のコメントが表示されjson3.jsます。

// Cyclic structures cannot be serialized by `JSON.stringify`.

この問題は、json3.jsの次の行に起因するようです:

// Manually invoke the callback for the `constructor` property due to
// cross-environment inconsistencies.
if (isConstructor || isProperty.call(object, (property = "constructor"))) {
    callback(property);
}

しかし、サイクルがあってはなりません。一体何が起こっているのかを知ることができないのは明らかです。

デバッグ中に手動でオブジェクトを作成すると、すべて正常に動作します。

では、何がエラーを引き起こす可能性がありますか?


編集:
エラーを生成するシナリオの準備に成功しました:

  • IE7 および IE8 互換モードの IE9 で発生します (Firefox 22 でも問題ありません)。
  • オープナーウィンドウからのデータを参照する新しいウィンドウが開かれた場合に発生します



*JSON_Cycle.html*:

    <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="http://bestiejs.github.io/json3/lib/json3.js"></script>
    <script>
    var dataGlobal = {mandant: "Hallo Welt!", personalNummer: 123456};
        $(function() {
            window.open("JSON_Cycle_Popup.html", 'popup');
        });
    </script>



*JSON_Cycle_Popup.html*:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="http://bestiejs.github.io/json3/lib/json3.js"></script>
<script>
    var dataGlobal = null;
    $(function() {
        dataGlobal = window.opener.dataGlobal;
        alert(JSON.stringify(dataGlobal));
    });
</script>
4

2 に答える 2

1

シリアル化する前に、コンストラクター関数を設定する必要があります。

key.constructor = function() {};

編集:
しかし、これはオブジェクトでのみ機能します! 配列では、同様の問題があります。しかし、ここでは上記の修正は機能しません!

この場合、実際の配列を文字列化すると、インデックス 0 の新しい配列にパックされます。興味深いことに、実際の配列のコンストラクターは依然として関数です。BUT: インデックス 1 と 2 に 2 つの追加のオブジェクトがあり、それらもオブジェクトです。しかし、JSON ライブラリの外部から操作できないようです。

最後まで理解したり、JSON を変更してテストしたりする時間と神経がありません。したがって、要素を新しい要素に入れるエレガントでない方法を使用します(クローンではありません->結果は同じエラーになります):

$.each(fahrzeuge, function() {
    zugNummern.push(this);
});

いくつかの要素しかないため、パフォーマンスが高くなく、それを実行できます。しかし、誰かがより良い解決策を投稿してくれれば幸いです。

于 2013-07-16T09:57:27.183 に答える
1

あなたの質問の新しい情報に基づいて、何が起こっているのかを説明できるようになりました。

JSON_Cycle.htmlファイルで、dataGlobal 変数が初期化された後に次の行を追加ます

alert(typeof dataGlobal.constructor);

JSON_Cycle_Popup.htmlで同じことを行います。違いに気づきましたか?IE では、最初のアラートでコンストラクターの型が「関数」であることが示されますが、ポップアップ ウィンドウでは、同じコンストラクターが「オブジェクト」の型を返します。

それが最初の問題です。次の問題は、json3 がオブジェクトのプロパティを列挙する方法から発生します。通常の for ループ、つまりfor (property in object) .... さまざまなブラウザー実装間の不一致を検出して、すべてのプラットフォームで同じ結果を返す列挙子を生成しようとする多くのコードがあります。

この列挙子の効果の 1つは、通常は for ループでコンストラクター プロパティが返されない場合でも、すべてのオブジェクトのコンストラクタープロパティを返すことです。いずれにせよ、コンストラクター関数を json オブジェクトでシリアライズしたくないことは明らかなので、これは完全に不必要に思えます。しかし、このコードは、その動作が望ましい他のプロジェクトから継承されたのではないかと思います。

これら 2 つの問題の組み合わせは、dataGlobalオブジェクトをシリアル化するときに、json3 が処理しようとするコンストラクタープロパティを見つけようとしていることを意味します。次に、そのコンストラクター(別のオブジェクトであると見なされます) をシリアル化するときに、別のコンストラクタープロパティ (これもオブジェクトのように見えます) を見つけます。次号がなければ、このプロセスは無限に続くでしょう。

4 レベルのコンストラクターの入れ子の後、関数ポインターは循環します。すなわち:

dataGlobal.constructor.constructor.constructor.constructor ==
dataGlobal.constructor.constructor

なぜそうなのかはわかりませんが、私がテストしたすべてのブラウザでそうなっているようです。これは、無限再帰を取得する代わりに、json3 コードがサイクルを検出してTypeError例外をスローすることを意味します。

それがあなたのエラーの説明です。IE のバグと、json3 プロパティ列挙子の不必要な巧妙さが組み合わさっています。

于 2013-07-22T19:06:58.613 に答える