Perf est aussi une raison. Parfois, vous pouvez avoir besoin de boucler sur des clés. Il y a plusieurs façons de le faire
for (let key in object) { ... }
for (let key in object) { if (object.hasOwnProperty(key) { ... } }
for (let key of Object.keys(object)) { ... }
J'utilise habituellement for of Object.keys()
comme il fait ce qu'il faut et est relativement laconique, il n'est pas nécessaire d'ajouter le contrôle.
Mais, c'est beaucoup plus lent .
Je devine juste la raison Object.keys
est lent est évident, Object.keys()
doit faire une allocation. En fait AFAIK il doit allouer une copie de toutes les clés depuis.
const before = Object.keys(object);
object.newProp = true;
const after = Object.keys(object);
before.join('') !== after.join('')
Il est possible que le moteur JS utilise une sorte de structure de clé immuable afin que Object.keys(object)
renvoie une référence quelque chose qui itère sur des clés immuables et qui object.newProp
crée un objet clé immuable entièrement nouveau mais peu importe, c'est clairement plus lent de 15x
Même en vérifiant hasOwnProperty
est jusqu'à deux fois plus lent.
Le point de tout cela est que si vous avez un code sensible à la perforation et que vous avez besoin de boucler sur les touches, vous voulez être en mesure d'utiliser for in
sans avoir à appeler hasOwnProperty
. Vous ne pouvez le faire que si vous n'avez pas modifié les éléments suivants Object.prototype
Notez que si vous utilisez Object.defineProperty
pour modifier le prototype si les éléments que vous ajoutez ne sont pas énumérables, ils n'affecteront pas le comportement de JavaScript dans les cas ci-dessus. Malheureusement, au moins dans Chrome 83, ils affectent les performances.
J'ai ajouté 3000 propriétés non dénombrables pour essayer de forcer l'apparition de problèmes de performance. Avec seulement 30 propriétés, les tests étaient trop serrés pour pouvoir dire s'il y avait un impact sur les performances.
https://jsperf.com/does-adding-non-enumerable-properties-affect-perf
Firefox 77 et Safari 13.1 ne montrent aucune différence de performance entre les classes augmentées et non augmentées. Peut-être que la v8 sera corrigée dans ce domaine et que vous pourrez ignorer les problèmes de performance.
Mais, laissez-moi aussi ajouter qu'il y a l'histoire de Array.prototype.smoosh
. La version courte est que Mootools, une bibliothèque populaire, a fait son propre Array.prototype.flatten
. Quand le comité de normalisation a essayé d'ajouter un natif Array.prototype.flatten
ils ont trouvé qu'on ne pouvait pas sans casser beaucoup de sites. Les développeurs qui ont découvert la rupture ont suggéré de nommer la méthode es5. smoosh
comme une blague mais les gens ont paniqué sans comprendre que c'était une blague. Ils se sont mis d'accord sur flat
au lieu de flatten
La morale de l'histoire est que vous ne devriez pas étendre les objets natifs. Si vous le faites, vous risquez de rencontrer le même problème de casse de votre matériel et, à moins que votre bibliothèque particulière ne soit aussi populaire que MooTools, il est peu probable que les fournisseurs de navigateurs travaillent sur le problème que vous avez causé. Si votre bibliothèque devient aussi populaire, ce serait un peu méchant de forcer tout le monde à contourner le problème que vous avez causé. Donc, s'il vous plaît Ne pas étendre les objets natifs