60 votes

JavaScript : Quels sont les dangers de l'extension de Array.prototype ?

Guide de style JavaScript de Google déconseille d'étendre le Array.prototype . Cependant, j'ai utilisé Array.prototype.filter = Array.prototype.filter || function(...) {...} comme un moyen de l'avoir (et des méthodes similaires) dans des navigateurs où ils n'existent pas. MDN fournit actuellement exemple similaire .

Je suis au courant de Object.prototype mais Array n'est pas une table de hachage.

Quels problèmes peuvent survenir lors de l'extension Array.prototype qui a poussé Google à le déconseiller ?

86voto

Jamund Ferguson Points 6338

La plupart des gens n'ont pas compris ce qui s'est passé. Le polyfilling ou le shimming de fonctionnalités standard comme Array.prototype.filter pour qu'il fonctionne dans les anciens navigateurs est une bonne idée à mon avis. N'écoutez pas les détracteurs. Mozilla vous montre même comment faire sur le MDN. Habituellement, les conseils pour ne pas étendre Array.prototype ou d'autres prototypes natifs pourrait se résumer à l'un de ceux-ci :

  1. for..in pourrait ne pas fonctionner correctement
  2. Quelqu'un d'autre pourrait également vouloir étendre Array avec le même nom de fonction.
  3. Il se peut qu'il ne fonctionne pas correctement dans tous les navigateurs, même avec la cale.

Voici mes réponses :

  1. Vous n'avez pas besoin d'utiliser for..in sur Array d'habitude. Si vous le faites, vous pouvez utiliser hasOwnProperty pour être sûr que c'est légitime.
  2. N'étendez les natifs que lorsque vous savez que vous êtes le seul à le faire. OU alors qu'il s'agit de choses standard comme Array.prototype.filter .
  3. C'est ennuyeux et ça m'a piqué. Le vieil IE a parfois des problèmes pour ajouter ce genre de fonctionnalité. Il faut voir si cela fonctionne au cas par cas. Pour moi, le problème était d'ajouter Object.keys à IE7. Il semblait ne plus fonctionner dans certaines circonstances. Votre kilométrage peut varier.

Vérifiez ces références :

Bonne chance !

12 votes

"Vous n'avez pas besoin d'utiliser for..in" -- ne l'utilisez pas du tout. Même avec hasOwnProperty tu vas quand même enjamber length ce qui n'a aucun sens dans la plupart des cas.

2 votes

@Malvolio Pas d'accord : Vous ne pouvez pas facilement savoir / contrôler ce qui se trouve dans vos bibliothèques tierces. Par exemple, for..in casse dans le chargeur SEA3D pour Three.js, avec mes ajouts à Array.prototype . En fait, une grande partie de three.js utilise for..in . Vraiment, ATTENTION. Ce ne sont pas des bugs agréables à trouver.

0 votes

@mrdoob Cela pourrait-il valoir la peine d'être examiné ?

9voto

jsumners Points 6247

Je vais vous donner les points, avec les phrases clés, de l'excellent article de Nicholas Zakas JavaScript maintenable : Ne modifiez pas les objets que vous ne possédez pas :

  • Fiabilité : "L'explication simple est qu'un logiciel d'entreprise a besoin d'un environnement d'exécution cohérent et fiable pour être maintenable."
  • Implémentations incompatibles : "Un autre péril de la modification d'objets qui ne vous appartiennent pas est la possibilité de collisions de noms et d'implémentations incompatibles."
  • Et si tout le monde le faisait ? : "Pour faire simple : si tous les membres de votre équipe modifiaient des objets qui ne leur appartiennent pas, vous seriez rapidement confrontés à des collisions de noms, à des implémentations incompatibles et à des cauchemars de maintenance."

En gros, ne le faites pas. Même si votre projet ne sera jamais utilisé par quelqu'un d'autre, et que vous n'allez jamais importer du code tiers, ne le faites pas. Vous prendrez une mauvaise habitude dont vous aurez du mal à vous défaire lorsque vous commencerez à essayer de coopérer avec les autres.

2 votes

Il n'y a rien de mal à étendre les objets hôtes pour les rendre conformes aux normes si l'équipe y consent. L'extension d'objets hôtes avec des propriétés non standard est une autre affaire, et je serais d'accord pour dire "ne le faites pas".

1 votes

Toute raison que vous pouvez trouver pour modifier les objets de l'hôte peut facilement être surmontée en mettant en œuvre la fonctionnalité sur vos propres objets. La documentation de l'environnement hôte n'inclut pas vos modifications. Cela peut être source de confusion, quel que soit l'accord de l'"équipe". Qu'en est-il du nouveau venu qui ne connaît pas toutes les modifications de l'hôte, mais à qui vous avez dit qu'il pouvait changer les objets de l'hôte ? Les choses peuvent se casser en un rien de temps.

3 votes

Ce raisonnement dans le fait déconseille la POO

3voto

Raynos Points 82706

Extension du site Array.prototype dans votre propre code d'application est sans danger (sauf si vous utilisez for .. in sur les tableaux, auquel cas vous devez payer pour cela et vous amuser à les refacturer).

L'extension des objets hôtes natifs dans les bibliothèques que vous voulez que d'autres utilisent n'est pas cool. Vous n'avez pas le droit de corrompu l'environnement des autres personnes dans votre propre bibliothèque.

Soit vous le faites derrière une méthode facultative comme lib.extendNatives() ou avoir [].filter comme une exigence.

Extension des objets natifs et des objets hôtes

3voto

wadim Points 132

Prototype fait ça. C'est diabolique. L'extrait suivant montre comment cela peut produire des résultats inattendus :

<script language="javascript" src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js"></script>
<script language="javascript">
  a = ["not", "only", "four", "elements"];
  for (var i in a)
    document.writeln(a[i]);
</script>

Le résultat :

not only four elements function each(iterator, context) { var index = 0; . . .

et environ 5000 caractères de plus.

4 votes

Ils ne sont pas mauvais, ce qui est mauvais c'est votre code, si vous l'enveloppez dans .hasOwnProperty seules ses propres propriétés apparaissent, sans vouloir vous offenser

1 votes

Je pense qu'il n'est pas syntaxiquement élégant d'utiliser .hasOwnProperty pour itérer sur un tableau.

1 votes

Pourquoi utiliser for ... in au lieu de forEach ? Pas besoin de has ownproperty ou de s'embrouiller avec les variables de portée.

2voto

Tikhon Jelvis Points 30789

Certaines personnes utilisent for ... in boucles pour itérer dans les tableaux. Si vous ajoutez une méthode au prototype, la boucle essaiera également d'itérer dans des tableaux. que clé. Bien sûr, vous ne devrait pas l'utiliser pour cela, mais certaines personnes le font quand même.

0 votes

Ils pensent que ce qu'ils sont itératif mais en réalité, ils sont énumération de :-) Un tel code est déjà cassé, il n'y a aucun intérêt à le soutenir de toute façon.

0 votes

Il s'agit d'un code stupide, certes, mais il faut quand même en être conscient : si vous ajoutez quelque chose au prototype et que vous commencez à avoir des bugs bizarres, cela peut être dû à cela.

0 votes

Ce que je veux dire, c'est que ce piège suppose que l'on soit déjà tombé dans le piège :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X