Ошибка "Слишком большая рекурсия" при использовании intanceof over typeof?

90
13

Я делал функцию для преобразования всех дат в объект в строки, и когда я использовал следующую функцию, я получил ошибку в FF "слишком много рекурсии". (Он также терпит неудачу в IE и хром)


    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;
}

Это должно быть такое же количество рекурсии. Я что-то упускаю? Почему я получаю ошибку с первым примером, но не вторым?


Обновление:
вот пример объекта, который я использовал (в 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. ASP.Net ScriptManager прототипирует методы для функции, которая вызывает цикл бесконечности при выполнении рекурсивного цикла for в функции.

спросил(а) 2021-01-25T19:55:53+03:00 5 месяцев назад
1
Решение
100

(Во-первых, позвольте мне сказать, что я пробовал свой код на FF 3.5.7, и он не запускался в бесконечную рекурсию. Может быть, вы использовали другой пример ввода?)


В любом случае, чтобы ответить на ваши вопросы:

(a) Почему вы получаете бесконечную рекурсию? Потому что объект может ссылаться на себя. Если o.f==o, то вызов вашей функции на o приведет к последующему вызову на o.f, который на самом деле o и так далее...


(b) Почему разница между двумя версиями? obj instanceof Object проверяет, является ли obj экземпляром Object или экземпляром его подкласса. Учитывая, что каждый объект Javascript наследуется от Object, тогда это условие тривиально верно и, следовательно, не имеет смысла. Чистым результатом является то, что первый if всегда преуспевает. С другой стороны, typeof obj == "object" проверяет, что obj является экземпляром Object. Это может быть неверно, например, если obj является экземпляром String (в этом случае typeof obj дает String). Следовательно, разница.

ответил(а) 2021-01-25T19:55:53+03:00 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема