TL; DR: Добавление каких-либо не встроенных функций в Array.prototype И Function.prototype заставит исходный JSON-анализатор IE8 получить переполнение стека при анализе любого JSON, содержащего массив, но только тогда, когда вы также передаете функцию reviver в JSON.parse().
Это началось как вопрос, но я ответил на свой собственный оригинальный вопрос, поэтому теперь я спрошу: может ли кто-нибудь подумать об обходном пути для этой ошибки IE8, которая не включает в себя устранение всех JS-библиотек, которые изменяют Array. прототип и Function.prototype?
Оригинальный вопрос:
У меня есть около 13k данных JSON для разбора. Структура данных - это объект с единственным значением, являющимся вложенным массивом.
{ 'value':[[ stuff ], [ more stuff], [ etc ]] }
Я использую json2.js, который отдает предпочтение браузерному родному JSON.parse, когда он доступен. Я передаю функцию reviver в JSON.parse для правильной обработки дат. Когда IE8 находится в режиме эмуляции IE7 (что заставляет его использовать парсер json2.js, основанный на script), все работает нормально. Когда IE8 находится в режиме IE8 (что заставляет его использовать собственный анализатор JSON на основе браузера), он взрывается с ошибкой "из пространства стека". Firefox и Chrome, конечно же, отлично работают с их парсерами JSON, основанными на браузере.
Я сузился до этого: если я передам в JSON.parse даже функцию do-nothing reviver, исходный парсер IE8 получит переполнение стека. Если я не передаю функцию reviver, собственный парсер IE8 отлично работает, за исключением того, что он правильно не обрабатывает даты.
// no error:
JSON.parse(stuff);
// "out of stack space" error:
JSON.parse(stuff, function(key, val) { return val; });
Я буду играть со своими данными JSON, чтобы увидеть, может ли меньше данных или меньше вложенности данных избежать ошибки, но мне было интересно, видел ли кто-нибудь это раньше или какие-либо другие предлагаемые варианты работы. IE8 уже достаточно медленный, было бы позором отключить собственный JSON для этого браузера из-за этой ошибки.
UPDATE: В других случаях, при использовании разных данных JSON, я получаю ошибку javascript "$ lineinfo is undefined", когда я использую собственный синтаксический анализатор IE8 с функцией reviver, и нет ошибки, если я не использую функцию reviver, Строка "$ lineinfo" не отображается нигде ни в одном из моих исходных кодов.
ОБНОВЛЕНИЕ 2: На самом деле эта проблема, по-видимому, вызвана прототипом 1.6.0.3. Мне не удалось воспроизвести его на отдельной тестовой странице, пока я не добавлю в библиотеку Prototype.
ОБНОВЛЕНИЕ 3:
Причина, по которой prototype.js ломает собственный синтаксический анализатор JSON IE8, заключается в следующем: добавление каких-либо не встроенных функций в Array.prototype И Function.prototype заставит исходный JSON-анализатор IE8 получить переполнение стека при анализе любого JSON, который содержит массив, но только тогда, когда вы также передаете функцию reviver в JSON.parse().
Библиотека Prototype добавляет функции как для Array.prototype, так и для Function.prototype, но это в равной степени относится к любой другой библиотеке, которая делает то же самое. Эта ошибка в синтаксисе IE JSON отображается Prototype и Ext, но не jQuery. Я не тестировал другие структуры.
Вот полностью автономное воспроизведение проблемы. Если вы удалите строку Function.prototype или строку Array.prototype или удалите массив из строки JSON, вы не получите ошибку "из пространства стека".
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
Function.prototype.test1 = function() { };
Array.prototype.test2 = function() { };
window.onload = function()
{
alert(JSON.parse('{ "foo": [1,2,3] }', function(k,v) { return v; }));
}
</script>
</head>
<body>
</body>
</html>