Avec un tableau JavaScript, je peux le réinitialiser à un état vide avec une seule affectation:
array.length = 0;
Cela fait «apparaître» le tableau vide et prêt à être réutilisé, et pour autant que je sache, il s'agit d'une seule «opération» - c'est-à-dire du temps constant.
Existe-t-il une méthode similaire pour effacer un objet JS? Je sais que je peux itérer ses champs en les supprimant:
for (var prop in obj) { if (obj.hasOwnProperty(prop)) { delete obj[prop]; } }
mais cela a une complexité linéaire.
Je peux aussi simplement jeter l'objet et en créer un nouveau:
obj = {};
Mais la création "promiscuous" de nouveaux objets conduit à des problèmes avec Garbage Collection sur IE6. ( Comme décrit ici )
javascript
performance
Levik
la source
la source
for (var prop in obj)
Réponses:
La réponse courte à votre question, je pense, est non (vous pouvez simplement créer un nouvel objet).
Dans cet exemple, je pense que la définition de la longueur à 0 laisse toujours tous les éléments pour le ramasse-miettes.
Vous pouvez l'ajouter à Object.prototype si c'est quelque chose que vous utilisez fréquemment. Oui, sa complexité est linéaire, mais tout ce qui ne fera pas de ramasse-miettes plus tard le sera.
C'est la meilleure solution. Je sais que ce n'est pas lié à votre question - mais pendant combien de temps devons-nous continuer à soutenir IE6? Il existe de nombreuses campagnes pour arrêter son utilisation.
N'hésitez pas à me corriger s'il y a quelque chose d'incorrect ci-dessus.
la source
Eh bien, au risque de rendre les choses trop faciles ...
... semble être assez efficace pour nettoyer l'objet dans une ligne de code avec un minimum de crochets effrayants. Tous les membres seront vraiment supprimés au lieu d'être laissés à la poubelle.
Évidemment, si vous souhaitez supprimer l'objet lui-même, vous devrez toujours faire un delete () séparé pour cela.
la source
hasOwnProperty
dans cette boucle. J'ai lu la documentation, mais j'essaie toujours de comprendre quels sont les risques, le cas échéant, si nous omettons lehasOwnProperty()
chèque?ES5
La solution ES5 peut être:
ES6
Et la solution ES6 peut être:
Performance
Quelles que soient les spécifications, les solutions les plus rapides seront généralement:
La raison pour laquelle
for..in
ne doit être effectué que sur un objet peu profond ou simple est qu'il traverse les propriétés qui sont héritées de manière prototypique, pas seulement les propriétés propres qui peuvent être supprimées. Dans le cas où l'on ne sait pas avec certitude qu'un objet est simple et que les propriétés sont énumérables,for
avecObject.getOwnPropertyNames
est un meilleur choix.la source
Vous pouvez essayer ceci. La fonction ci-dessous définit toutes les valeurs des propriétés de l'objet sur indéfinies. Fonctionne également avec les objets imbriqués.
la source
Donc, pour récapituler votre question: vous voulez éviter, autant que possible, les problèmes avec le bogue IE6 GC. Ce bug a deux causes:
La solution à la cause 1 semble être: réduire le nombre d'allocations; attribuez le moins possible de nouveaux objets et chaînes.
La solution à la cause 2 semble être: réduire le nombre d'objets «vivants»; supprimez vos chaînes et objets dès que vous n'en avez plus besoin et créez-les à nouveau si nécessaire.
Dans une certaine mesure, ces solutions sont contradictoires: maintenir le nombre d'objets en mémoire bas entraînera davantage d'allocations et de désallocations. À l'inverse, réutiliser constamment les mêmes objets pourrait signifier garder plus d'objets en mémoire que strictement nécessaire.
Maintenant pour votre question. Que vous réinitialisiez un objet en créant un nouveau, ou en supprimant toutes ses propriétés: cela dépendra de ce que vous voulez en faire par la suite.
Vous voudrez probablement lui attribuer de nouvelles propriétés:
Il n'y a pas de moyen rapide et facile à utiliser pour effacer un objet JScript pour le réutiliser comme s'il s'agissait d'un nouvel objet - sans en créer un nouveau. Ce qui signifie que la réponse courte à votre question est «Non», comme le dit jthompson.
la source
Quelque chose de nouveau à penser dans l'attente d'Object.observe dans ES7 et avec la liaison de données en général. Considérer:
Donc, dans cette circonstance, le n ° 2 peut être le meilleur choix.
la source
obj = {}
rendra le framework inconscient de toute modification ultérieure de l'objet, donc vos modèles ne seront pas correctement rendus. L'option n ° 2 fonctionnera cependant correctement.Vous pouvez supprimer les accessoires, mais ne supprimez pas les variables.
delete abc;
n'est pas valide dans ES5 (et lance avec use strict).Vous pouvez l'attribuer à null pour le définir pour la suppression dans le GC (ce ne sera pas le cas si vous avez d'autres références à des propriétés)
Définir une
length
propriété sur un objet ne change rien. (il ne définit que la propriété)la source
length
à 0 sur un tableau (qui est un type d'objet spécifique - si vous ne me croyez pas, essayez de courirtypeof []
), cela ne définira pas seulement la propriété, cela effacera en fait le contenu du tableau . Voir stackoverflow.com/questions/1232040/…window.abc
car c'est un accessoire dans ce cas.Cela m'a dérangé pendant des siècles alors voici ma version car je ne voulais pas d'objet vide, j'en voulais un avec toutes les propriétés mais réinitialisé à une valeur par défaut. Un peu comme une nouvelle instanciation d'une classe.
la source