L'ajout d'une fonction à Array.prototype dans IE entraîne son insertion dans chaque matrice en tant qu'élément

J'ai ajouté le polyfill suivant à Array au début de mon projet:

 if (!Array.prototype.find) { Array.prototype.find = function(predicate) { if (this === null) { throw new TypeError('Array.prototype.find called on null or undefined'); } if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } var list = Object(this); var length = list.length >>> 0; var thisArg = arguments[1]; var value; for (var i = 0; i < length; i++) { value = list[i]; if (predicate.call(thisArg, value, i, list)) { return value; } } return undefined; }; } 

Cela fonctionne parfaitement bien dans Chrome et Firefox, mais sur Internet Explorer 11, cette fonction est en train d'être poussée dans chaque Array comme élément de celui-ci, et je peux même l'accéder comme suit:

 var a = []; a[0](); 

Ceci lance toutes sortes d'exceptions dans IE avec des fonctions comme. Pour .forEach endroit où j'attends certaines données et cette fonction est trouvée.

Voici une capture d'écran des outils de développement d'IE, dans ce cas, ce tableau devrait avoir seulement 2 éléments, au lieu de 3.

IE - faux

Et c'est comme ça qu'il devrait être, à partir de Chrome. En fait, je crois que même le contenu réel est faux, mais je ne suis pas encore arrivé (il devrait s'agir d'un tableau contenant des tableaux de longueur 2).

Chrome - correct

Comment JavaScript peut-il se comporter si mal dans IE11 et comment puis-je correctement ajouter cette fonction au prototype au lieu de dans chaque instance Array ?

Ce n'est pas «poussé» dans chaque gamme; Vous avez ajouté une propriété à l'objet prototype, donc il est visible et énumérable dans chaque instance de tableau. C'est ainsi que les propriétés prototypes sont supposées fonctionner.

Il fonctionne dans Chrome et Firefox parce que .find() sur le prototype dans ces environnements est défini de manière à être visible mais non énumérable . Vous pouvez le faire dans IE en utilisant Object.defineProperty() :

 if (!Array.prototype.find) { Object.defineProperty(Array.prototype, "find", { value: function(predicate) { if (this === null) { throw new TypeError('Array.prototype.find called on null or undefined'); } if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } var list = Object(this); var length = list.length >>> 0; var thisArg = arguments[1]; var value; for (var i = 0; i < length; i++) { value = list[i]; if (predicate.call(thisArg, value, i, list)) { return value; } } return undefined; } }); } 

En plus de la «valeur» de la propriété, qui est clairement la valeur de la nouvelle propriété, les propriétés «énumérables» et «configurables» par défaut sont false . Cela signifie que la "recherche" ne s'affichera pas dans une situation qui implique l'itération via les propriétés de l'objet.