Pourquoi l'extension des prototypes d'objets DOM / intégrés est-elle une mauvaise idée?


15

Je cherche une réponse définitive à la raison pour laquelle l'extension des prototypes intégrés est si fortement châtiée dans la communauté des développeurs JS. J'utilise le framework Prototype JS depuis un certain temps, et pour moi, cela [1,2,3].each(doStuff)semble beaucoup plus élégant que $.each([1,2,3], doStuff). Je sais que cela crée une "pollution de l'espace de noms", mais je ne comprends toujours pas pourquoi c'est considéré comme une mauvaise chose. Y a-t-il également une dégradation réelle des performances associée à l'extension des prototypes intégrés? Merci!


1
Une chose est que les for(var ... in ...)boucles sont gâchées car les fonctions prototypes sont également passées.
pimvdb

4
"fortement châtié", vraiment?! bon dieu, mec:] tu vas bien?
pixelbobby

Réponses:


12

Je vous suggère de lire cet article qui, je pense, explique assez bien pourquoi l'extension d'objets est une mauvaise idée, en ce qui concerne Prototype également.

En résumé:

Manque de spécifications

L'exposition des "objets prototypes" ne fait partie d'aucune spécification. [...] Pour que l'implémentation soit entièrement conforme au DOM niveau 2, il n'est pas nécessaire d'exposer ces objets Node, Element, HTMLElement, etc. globaux.

Les objets hôtes n'ont pas de règles

Les objets DOM sont des objets hôtes [...] Les objets hôtes peuvent implémenter ces méthodes internes avec n'importe quel comportement dépendant de l'implémentation, ou il se peut qu'un objet hôte implémente uniquement certaines méthodes internes et pas d'autres.

[...] Le comportement des méthodes internes dépend de l'implémentation. [...] Par définition, vous travaillez avec quelque chose qui peut se comporter de manière imprévisible et complètement erratique.

Risque de collisions

Étant donné la grande quantité d'environnements utilisés aujourd'hui, il devient impossible de dire si certaines propriétés ne font pas déjà partie de certains DOM. [...]

Toutes les propriétés d'ombres de contrôle de formulaire nommées héritées de la chaîne de prototypes. Le risque de collisions et d'erreurs inattendues sur les éléments de formulaire est encore plus élevé.

L'utilisation d'une sorte de stratégie de préfixe peut atténuer le problème. Mais cela apportera probablement aussi du bruit supplémentaire.

Frais généraux de performance

[...] les navigateurs qui ne prennent pas en charge les extensions d'éléments - comme IE 6, 7, Safari 2.x, etc. - nécessitent une extension d'objet manuelle. Le problème est que l'extension manuelle est lente, peu pratique et n'est pas évolutive.

[...] une fois que vous commencez à étendre des éléments, l'API de bibliothèque doit très probablement renvoyer des éléments étendus partout. Par conséquent, des méthodes de requête telles que $$ pourraient finir par étendre chaque élément d'une requête.

IE DOM est un gâchis

Comme indiqué dans la section précédente, l'extension DOM manuelle est un gâchis. Mais l'extension DOM manuelle dans IE est encore pire [...]

Bonus: les bugs du navigateur


9

Une autre raison est la lisibilité / maintenabilité du code. Si un autre développeur (en particulier un débutant) lit mon code et voit [0, 1, 2].foo(...), il peut ne pas savoir quelle est la méthode foo ou où trouver la documentation / source pour cela. Est-ce que foo est une extension du langage ajouté par prototype.js, ou par une autre bibliothèque en cours d'utilisation, ou par une autre partie de mon code dans un autre fichier, ou est-ce une méthode JavaScript native qu'ils ne connaissaient pas? Ils ont besoin de le rechercher et peuvent ne pas le trouver tout de suite (ou s'il y a des conflits, ils peuvent ne pas trouver le bon).

Avec l'approche jQuery, si vous voyez $.foo(...), l'espace de noms de la méthode foo rend évident où trouver sa définition / documentation si vous ne savez pas ce qu'elle fait.


La possibilité de découvrir d'où viennent les méthodes est très importante pour les lecteurs. Bien que je ne pense pas vraiment que jQuery soit un bon exemple car le signe dollar est difficile à rechercher lorsque vous vous lancez dans la lecture de code Web et ne savez pas déjà ce que c'est.
Simon Feltman

4

Voici le problème de base: que se passe-t-il si vous disposez de deux outils qui étendent les prototypes de manière incompatible ou qui étendent les méthodes communément appelées de manière à produire des résultats différents (c'est un problème particulier pour for...inJavaScript), provoquant ainsi un code qui repose sur sur leur comportement normal pour briser?

Fondamentalement, ce sont les mêmes problèmes que vous rencontrez lorsque vous utilisez mal les variables globales. En soi, il ne se passe peut-être rien de mal. Mais, cela vous ouvre des problèmes lorsque deux morceaux de code ostensiblement séparés se marchent soudainement (et c'est difficile de déboguer lorsque cela se produit).

Certes, prototype.js est assez bien connu et la plupart des outils fonctionnent autour de ce qu'il fait. De même, je suis sûr qu'il existe des cas où l'extension des prototypes de base est la bonne chose à faire. Mais c'est quelque chose à aborder avec prudence.


1

Je ne sais pas si c'est vraiment toujours un problème, mais mon expérience avec les versions antérieures d'Internet Explorer est que parfois il n'était même pas possible d'étendre certains types de build-in.


1

Il y a deux problèmes distincts ici. Le premier est l'extension générale des prototypes intégrés, et l'autre étend spécifiquement les prototypes DOM. Les arguments contre l'extension des prototypes intégrés:

  • Conflits potentiels: deux morceaux de code provenant de sources différentes définissant tous deux la même propriété sur le même prototype
  • Effets secondaires: étendre Array.prototypeou Object.prototypepeut avoir des effets d'entraînement, comme l'ajout des méthodes d'extension énumérées dans une for...inboucle

Quant à l'extension des prototypes DOM, l'argument de conflit potentiel ci-dessus s'applique toujours. De plus, les nœuds DOM sont des objets hôtes et en tant que tels ne sont soumis à aucune des règles normales des objets JavaScript natifs. Ils peuvent essentiellement faire ce qu'ils veulent et n'ont aucune obligation de fournir des objets prototypes sensibles ou même d'autoriser des propriétés supplémentaires ("expando"). IE à des exercices particuliers ce droit, à condition qu'aucun prototype pour les objets DOM avant IE 9 et ayant différentes propriétés sur bizarreries sur les différents objets DOM (bien que vous êtes propriétés généralement OK à Assigner des éléments fournis, l'ensemble de rien document.expandoà false.)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.