Com uma matriz JavaScript, posso redefini-la para um estado vazio com uma única atribuição:
array.length = 0;
Isso faz com que o Array "pareça" vazio e pronto para reutilização, e até onde eu entendo é uma "operação" única - ou seja, tempo constante.
Existe uma maneira semelhante de limpar um objeto JS? Eu sei que posso iterar seus campos excluindo-os:
for (var prop in obj) { if (obj.hasOwnProperty(prop)) { delete obj[prop]; } }
mas isso tem complexidade linear.
Também posso jogar o objeto fora e criar um novo:
obj = {};
Mas a criação "promíscuo" de novos objetos leva a problemas com a Coleta de Lixo no IE6. ( Como descrito aqui )
javascript
performance
levik
fonte
fonte
for (var prop in obj)
Respostas:
A resposta curta para sua pergunta, eu acho, é não (você pode apenas criar um novo objeto).
Neste exemplo, acredito que definir o comprimento como 0 ainda deixa todos os elementos para coleta de lixo.
Você pode adicionar isso ao Object.prototype se for algo que você usaria com frequência. Sim, é linear em complexidade, mas qualquer coisa que não faça coleta de lixo mais tarde será.
essa é a melhor solução. Sei que não está relacionado à sua pergunta - mas por quanto tempo precisamos continuar apoiando o IE6? Existem muitas campanhas para interromper o uso dela.
Fique à vontade para me corrigir se houver algo incorreto acima.
fonte
Bem, correndo o risco de facilitar as coisas ...
... parece ser bastante eficaz na limpeza do objeto em uma linha de código com um mínimo de colchetes assustadores. Todos os membros serão realmente excluídos em vez de deixados como lixo.
Obviamente, se você deseja excluir o objeto em si, ainda precisará fazer um delete () separado para isso.
fonte
hasOwnProperty
nesse loop. Eu li os documentos, mas ainda estou tentando entender quais são os riscos, se houver, se omitirmos ohasOwnProperty()
cheque.ES5
A solução ES5 pode ser:
ES6
E a solução ES6 pode ser:
atuação
Independentemente das especificações, as soluções mais rápidas serão geralmente:
A razão pela qual
for..in
deve ser realizada apenas em objetos rasos ou simples é que ela percorre as propriedades herdadas prototipicamente, não apenas as propriedades próprias que podem ser excluídas. No caso, não se sabe ao certo que um objeto é simples e propriedades são enumeráveis,for
comObject.getOwnPropertyNames
é uma escolha melhor.fonte
Você pode tentar isso. A função abaixo define todos os valores das propriedades do objeto como indefinidos. Funciona bem com objetos aninhados.
fonte
Então, para recapitular sua pergunta: você deseja evitar, tanto quanto possível, problemas com o bug do IE6 GC. Esse bug tem duas causas:
A solução para causar 1 parece ser: mantenha o número de alocações baixo; atribua novos objetos e cadeias o mínimo possível.
A solução para causar 2 parece ser: mantenha o número de objetos "vivos" baixos; exclua suas strings e objetos assim que não precisar mais deles e crie-os novamente quando necessário.
Até certo ponto, essas soluções são contraditórias: manter baixo o número de objetos na memória exigirá mais alocações e desalocações. Por outro lado, reutilizar constantemente os mesmos objetos pode significar manter mais objetos na memória do que o estritamente necessário.
Agora a sua pergunta. Se você redefinirá um objeto criando um novo ou excluindo todas as suas propriedades: isso dependerá do que você deseja fazer com ele posteriormente.
Você provavelmente desejará atribuir novas propriedades a ele:
Não existe uma maneira rápida e fácil de limpar um objeto JScript para reutilização como se fosse um novo objeto - sem criar um novo. O que significa que a resposta curta para sua pergunta é 'Não', como jthompson diz.
fonte
Algo novo para se pensar em aguardar Object.observe no ES7 e com a ligação de dados em geral. Considerar:
Portanto, nessa circunstância 2, pode ser a melhor escolha.
fonte
obj = {}
fará com que a estrutura não tenha conhecimento de qualquer alteração adicional no objeto, portanto, seus modelos não serão renderizados corretamente. A opção 2, no entanto, funcionará corretamente.Você pode excluir os objetos, mas não as variáveis.
delete abc;
é inválido no ES5 (e lança com o uso strict).Você pode atribuí-lo a null para configurá-lo para exclusão no GC (isso não acontecerá se você tiver outras referências a propriedades)
Definir
length
propriedade em um objeto não altera nada. (apenas define a propriedade)fonte
length
0 em uma matriz (que é um tipo específico de objeto - se você não acredita em mim, tente executartypeof []
), ela não apenas definirá a propriedade, como também limpará o conteúdo da matriz . Veja stackoverflow.com/questions/1232040/…window.abc
porque é um suporte nesse caso.Isso me incomodou por muito tempo, então aqui está minha versão, pois eu não queria um objeto vazio, queria um com todas as propriedades, mas redefinii para algum valor padrão. Como uma nova instanciação de uma classe.
fonte