TL;DR : L'ajout de toute fonction non intégrée à Array.prototype ET Function.prototype entraînera un dépassement de pile pour l'analyseur JSON natif d'IE8 lors de l'analyse de tout JSON contenant un tableau, mais uniquement lorsque vous passez également une fonction reviver dans JSON.parse().
Il s'agissait au départ d'une question, mais j'ai répondu à ma propre question initiale, alors je la pose maintenant : quelqu'un peut-il penser à une solution de contournement pour ce bug d'IE8 qui n'implique pas l'élimination de toutes les bibliothèques JS qui modifient Array.prototype et Function.prototype ?
Question originale :
J'ai environ 13 000 données JSON à analyser. La structure des données est un objet avec une seule valeur qui est un tableau imbriqué.
{ 'value':[[ stuff ], [ more stuff], [ etc ]] }
J'utilise json2.js, qui s'en remet à la fonction JSON.parse native du navigateur lorsqu'elle est disponible. Je passe une fonction reviver dans JSON.parse pour gérer correctement les dates. Lorsque IE8 est en mode d'émulation IE7 (ce qui l'amène à utiliser le parseur json2.js basé sur script), tout fonctionne bien. Lorsque IE8 est en mode IE8 (ce qui lui fait utiliser l'analyseur JSON natif du navigateur), il explose avec une erreur "out of stack space". Firefox et Chrome, bien sûr, fonctionnent très bien avec leurs analyseurs JSON natifs.
J'ai réduit le problème à ceci : si je passe ne serait-ce qu'une fonction reviver do-nothing dans JSON.parse, le parseur natif d'IE8 obtient le dépassement de pile. Si je ne passe aucune fonction reviver, l'analyseur natif d'IE8 fonctionne bien, sauf qu'il n'analyse pas les dates correctement.
// no error:
JSON.parse(stuff);
// "out of stack space" error:
JSON.parse(stuff, function(key, val) { return val; });
Je vais jouer avec mes données JSON, pour voir si moins de données ou moins d'imbrication des données peuvent éviter l'erreur, mais je me demandais si quelqu'un avait déjà vu cela auparavant, ou avait d'autres suggestions de contournement. IE8 est déjà assez lent, il serait dommage de désactiver le JSON natif pour ce navigateur à cause de ce bug.
MISE À JOUR : Dans d'autres cas, avec des données JSON différentes, j'obtiens une erreur javascript "$lineinfo is undefined" lorsque j'utilise le parseur natif d'IE8 avec une fonction reviver, et aucune erreur si je n'utilise pas de fonction reviver. La chaîne "$lineinfo" n'apparaît nulle part dans mon code source.
MISE À JOUR 2 : En fait, ce problème semble être causé par Prototype 1.6.0.3. Je n'ai pas pu le reproduire dans une page de test isolée jusqu'à ce que j'ajoute la bibliothèque Prototype.
UPDATE 3 :
La raison pour laquelle prototype.js casse l'analyseur JSON natif d'IE8 est la suivante : L'ajout de toute fonction non intégrée à Array.prototype ET Function.prototype entraînera un dépassement de pile pour l'analyseur JSON natif d'IE8 lors de l'analyse de tout JSON contenant un tableau, mais uniquement si vous passez également une fonction reviver dans JSON.parse().
La bibliothèque Prototype ajoute des fonctions à Array.prototype et Function.prototype, mais cela s'applique également à toute autre bibliothèque qui fait la même chose. Ce bogue dans l'analyseur JSON d'IE est exposé par Prototype et Ext, mais pas par jQuery. Je n'ai pas testé d'autres frameworks.
Voici une reproduction complètement autonome du problème. Si vous supprimez la ligne Function.prototype, ou la ligne Array.prototype, ou si vous supprimez le tableau de la chaîne JSON, vous n'obtiendrez pas l'erreur "out of stack space".
<!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>