Perf est aussi une raison. Parfois, vous devrez peut-être boucler sur les clés. Il y a plusieurs moyens 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 généralement for of Object.keys()
comme il fait la bonne chose et est relativement concis, pas besoin d'ajouter le chèque.
Mais, c'est beaucoup plus lent .
Deviner simplement que la raison Object.keys
est lente est évidente, Object.keys()
il faut 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 de Object.keys(object)
renvoyer une référence quelque chose qui itère sur des clés immuables et qui object.newProp
crée un tout nouvel objet de clés immuables, mais quoi qu'il en soit, il est clairement plus lent jusqu'à 15x
Même la vérification hasOwnProperty
est jusqu'à 2 fois plus lente.
Le point de tout cela est que si vous avez du code sensible aux performances et que vous avez besoin de boucler sur des clés, vous voulez pouvoir l'utiliser for in
sans avoir à appeler hasOwnProperty
. Vous ne pouvez le faire que si vous n'avez pas modifié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 énumérables juste pour essayer de forcer l'apparition des problèmes de perf. Avec seulement 30 propriétés, les tests étaient trop proches pour 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 n'ont montré aucune différence de performance entre les classes augmentée et non augmentée. Peut-être que la v8 sera corrigée dans ce domaine et vous pouvez ignorer les problèmes de performance.
Mais permettez-moi également d'ajouter qu'il y a l'histoire deArray.prototype.smoosh
. La version courte est Mootools, une bibliothèque populaire, faite leur propre Array.prototype.flatten
. Lorsque le comité des normes a essayé d'ajouter un natif, Array.prototype.flatten
il a trouvé que le ne pouvait pas sans casser de nombreux sites. Les développeurs qui ont découvert la pause 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 installés au flat
lieu deflatten
La morale de l'histoire est que vous ne devez pas étendre les objets natifs. Si vous le faites, vous pourriez rencontrer le même problème de rupture de vos trucs et à moins que votre bibliothèque particulière ne soit aussi populaire que MooTools, il est peu probable que les fournisseurs de navigateurs contournent le problème que vous avez causé. Si votre bibliothèque devient aussi populaire, ce serait un peu moyen de forcer tout le monde à contourner le problème que vous avez causé. Alors, veuillez ne pas étendre les objets natifs