3

オブジェクト内のすべての日付を文字列に変換する関数を作成していましたが、次の関数を使用すると、FF で「再帰が多すぎます」というエラーが発生しました。(IEやchromeでも失敗します)

    function datesToString(obj) {
        if (obj instanceof Object) {
            if (obj instanceof Date) {
                obj = "this part does not matter";
            } else {
                for (var key in obj) { obj[key] = datesToString(obj[key]); }
            }
        }
        return obj;
    }

しかし、 typeof を使用するように変更すると、正常に機能しましたか?

    function datesToString(obj) {
        if (obj  && typeof obj == "object") {
            if (obj instanceof Date) {
                obj = "this part does not matter";
            } else {
                for (var key in obj) { obj[key] = datesToString(obj[key]); }
            }
        }
        return obj;
    }

同じ量の再帰でなければなりません。何か不足していますか?最初の例ではエラーが発生するのに、2 番目の例ではエラーが発生しないのはなぜですか?

更新:これは私が使用していたオブジェクトの例です(json形式)

Contact = {
    "LContactID": "00000000-0000-0000-0000-000000000000",
    "CellPhone": "",
    "HomePhone": "4564564560",
    "OtherPhone": "",
    "BirthDate": new Date(-62135575200000),
    "SSN": "456456456",
    "HowToContact": 1,
    "ContactType": 3,
    "Address1": "123 test",
    "Address2": "apt. 1",
    "City": "Valparaiso",
    "State": "IN",
    "Zip": "46383",
    "FullAddress": "123 test, apt. 1",
    "BuilderID": "",
    "FullAddressWithCityState": "123 test\r\napt. 1\r\nValparaiso, IN 46383",
    "WorkHours": "9-5",
    "ContactTime": "",
    "ContactMethod": "???",
    "IsMilitaryOrSelfEmployed": false,
    "AlternateContactName": "",
    "AlternateContactPhone": "",
    "ContactID": "00000000-0000-0000-0000-000000000000",
    "Password": null,
    "FirstName": "updatetest",
    "MiddleName": null,
    "LastName": "test_",
    "Suffix": null,
    "EmailAddress": null,
    "EmailAddressAlternate": null,
    "WorkPhone": "6546546540",
    "WorkPhoneExt": null,
    "CreatedOn": new Date(1263597309000),
    "CreatedOnOverride": new Date(-62135575200000),
    "ModifiedOn": new Date(1264014749000),
    "SCRep": "",
    "HBCRep": "",
    "PPPRep": "",
    "DPSRep": "",
    "DRSRep": "",
    "RDRep": "",
    "OwnerID": "00000000-0000-0000-0000-000000000000",
    "FullName": "updatetest test_",
    "ImportID": 0,
    "IncludeEmail": false,
    "PreferredLanguage": 1,
    "CarbonCopyList": [],
    "HearAboutUs": 5,
    "HearAboutUsOther": "",
    "init": function() { },
    "update": function() { },
    "load": function() { }
}

メソッドのパラメーター (init、update、load) を削除すると、instanceof の例で動作するように見えます。

更新: これは ASP.Net ScriptManager の問題であることが判明しました。ASP.Net Web サイトで作業していたという事実を含めずに申し訳ありません。ASP.Net ScriptManager は、関数に対して再帰的な for in ループを実行するときに無限ループを引き起こす Function のメソッドをプロトタイプ化します。

4

1 に答える 1

4

(最初に、FF 3.5.7 であなたのコードを試してみましたが、無限再帰にはなりませんでした。別の入力例を使用したのではないでしょうか?)

とにかく、あなたの質問に答えるために:

(a) 無限再帰が発生するのはなぜですか? オブジェクトはそれ自体を参照する可能性があるためです。o.f==o次に、関数を呼び出すと、実際にはo次の呼び出しが発生します...o.fo

(b) 2 つのバージョンの違いはなぜですか? obj instanceof Objectobj がそのサブクラスObjectのインスタンスまたはインスタンスであるかどうかを調べます。すべての Javascript オブジェクトが Object から継承されていることを考えると、この条件は自明であり、無意味です。最終的な結果は、最初のものが常に成功することです。一方、obj が Object のインスタンスであることを確認します。たとえば、が String のインスタンスである場合 (この場合は yields ) 、これは false になる可能性があります。したがって、違い。iftypeof obj == "object"objtypeof objString

于 2010-01-20T21:55:06.133 に答える