web-dev-qa-db-fra.com

Extension de JavaScript Object.prototype

Je ne demande pas si ça va.

Object.prototype.method = function(){};

Ceci est réputé diabolique par à peu près tout le monde, considérant que ça gâche for(var i in obj).

La vraie question

En ignorant

  • Navigateurs incompétents (navigateurs qui ne supportent pas Object.defineProperty)
  • Possibilité de collision ou de neutralisation de propriété

En supposant que vous ayez une incroyablement méthode utile, est-ce considéré comme faux/contraire à l'éthique?

Object.defineProperty(Object.prototype, 'methodOnSteriods',{
  value: function(){ /* Makes breakfast, solves world peace, takes out trash */ },
  writable: true,
  configurable: true,
  enumerable: false
});

Si vous croyez que ce qui précède est contraire à l'éthique, pourquoi auraient-ils même implémenté la fonctionnalité en premier lieu? 

33
William A

Je pense que c'est bien si cela fonctionne dans votre environnement cible.

De plus, je pense que la paranoïa d'extension du prototype est exagérée. Tant que vous utilisez hasOwnProperty() comme un bon développeur, tout va bien. Dans le pire des cas, vous surchargez cette propriété ailleurs et perdez la méthode. Mais c'est de ta faute si tu fais ça.

22
Alex Wayne

Je dirais que c'est presque aussi pervers qu'avant. Le plus gros problème, toujours le même, est que Object.prototype est global . Bien que votre méthode puisse actuellement résoudre le problème de la paix dans le monde, elle a peut-être écrasé la méthode de quelqu'un d'autre (qui garantissait la paix galactique) ou pourrait être écrasée à l'avenir par une bibliothèque sur laquelle vous n'avez aucun contrôle (ce qui replonge le monde dans le chaos)


Les nouvelles versions de Javascript comportent de nombreuses fonctionnalités liées aux propriétés, telles que la définition d'une propriété comme énumérable/non énumérable, la présence de getters et de setters ... Object.defineProperty existe pour en permettre le contrôle.

De Mozilla Docs :

Cette méthode permet d'ajouter ou de modifier avec précision une propriété Sur un objet. L'ajout de propriétés normales par affectation crée Des propriétés qui s'affichent lors de l'énumération des propriétés (pour ... en boucle), Dont les valeurs peuvent être modifiées et qui peuvent être supprimées. Cette méthode Permet de modifier ces détails supplémentaires par défaut.


Cette nouvelle fonction est essentiellement nécessaire pour prendre en charge les nouvelles fonctionnalités et vous êtes censé l’utiliser pour vos propres tâches. Pouvoir modifier Object.prototype n’est qu’un effet secondaire de son statut d’objet "normal" et est tout aussi pervers qu’auparavant.

10
hugomg

Eh bien, dans "JavaScript: les bonnes parties", il existe une fonction similaire, je pense que cela est très utile pour améliorer les objets de base en javascript (comme String, Date, etc.), mais rien que pour ça.

// Add a method conditionally. from "JavaScript: the good parts"

Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
}
3
sacabuche

.hasOwnProperty() exclura l'itération à travers les propriétés héritées, ce qui, selon moi, est souvent plus ennuyeux qu'utile. Cela annule en grande partie l'utilité de Object.create() - ce qui est ironique, car le même gars qui a convaincu tout le monde de faire .hasOwnProperty() a également promu Object.create().

Object.prototype ne doit pas être étendu, pour les raisons énumérées ici. Si vous voulez vraiment l'étendre, alors rendez les extensions non-itérables.

Je me rends compte que cela va à l’encontre de toutes les meilleures pratiques publiées, mais nous devrions vraiment arrêter de «mandater» .hasOwnProperty() sur les itérations de clé d’objet et admettre l’utilité de l’héritage direct entre objets.

3
Nomad128

La réponse courte est oui, vous devriez le faire.

Avant de le faire, il y a plusieurs précautions à prendre:
1. utiliser hasOwnProperty pour itérer un objet, mais ce n'est pas vraiment une précaution, quand j'itère un objet, j'utilise déjà hasOwnProperty de toute façon.
2. vérifier si la name dans Object.prototype.name a existé, ceci est très sûr pour éviter la collision de noms.
3. Tirez profit de Object.defineProperty(), ajoutez simplement une couche de sauvegarde supplémentaire.

Comme vous pouvez le constater, ce n’est pas très compliqué. 

Vient maintenant les avantages une fois que vous avez pris en compte les risques/inconvénients:
1. En chaînant les méthodes, cela rend le code plus lisible, plus concis, et rend le codage plus agréable. En retour, vous êtes plus heureux et votre vie plus facile.
2. résout le problème de compatibilité du navigateur, vous faites quand même du polyfill.

P.S .: 
Ne le faites pas lorsque vous travaillez avec une grande équipe.

0
alexcres