TL; DR: Добавление любых встроенных функций в Array.prototype И Function.prototype заставит исходный JSON-анализатор IE8 получать переполнение стека при анализе любого JSON, который содержит массив, но только когда вы также передаете функцию reviver в JSON.parse().Исходный код JSON.parse IE8 вызывает переполнение стека
Это началось как вопрос, но я ответил на свой собственный вопрос, поэтому теперь я спрошу: может ли кто-нибудь подумать об обходном пути для этой ошибки IE8, которая не включает в себя устранение всех JS-библиотек, которые изменяют Array.prototype и Function.prototype?
Оригинальный вопрос:
У меня есть около 13k данных JSON для синтаксического анализа. Структура данных - это объект с единственным значением, являющимся вложенным массивом.
{ 'value':[[ stuff ], [ more stuff], [ etc ]] }
Я использую json2.js, который отсылает браузер на родной JSON.parse, когда он доступен. Я передаю функцию reviver в JSON.parse для правильной обработки дат. Когда IE8 находится в режиме эмуляции IE7 (что заставляет его использовать скрипт json2.js на основе скрипта), все работает нормально. Когда 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 для этого браузера из-за этой ошибки.
ОБНОВЛЕНИЕ: В других случаях, при использовании разных данных JSON, я получаю ошибку javascript «$ lineinfo undefined», когда я использую собственный синтаксический анализатор IE8 с функцией reviver, и нет ошибки, если я не использую функцию reviver. Строка «$ lineinfo» не отображается нигде в каком-либо из исходного кода.
ОБНОВЛЕНИЕ 2: На самом деле эта проблема, по-видимому, вызвана Prototype 1.6.0.3. Мне не удалось воспроизвести его на изолированной тестовой странице, пока я не добавлю в библиотеку Prototype.
UPDATE 3:
Причина prototype.js разбивает IE8 родной JSON парсер это: Добавление любого не-встроенных функций Array.prototype И Function.prototype вызовут IE8 родной JSON парсер, чтобы получить переполнение стека при анализе любого 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>
Команда JavaScript сообщает, что это известная проблема в движке JavaScript. Благодарю. – EricLaw
Спасибо, что сообщили мне. –