Existe alguma maneira em javascript de criar uma "referência fraca" para outro objeto? Aqui está a página wiki que descreve o que é uma referência fraca. Aqui está outro artigo que os descreve em Java. Alguém pode pensar em uma maneira de implementar esse comportamento em javascript?
javascript
weak-references
Stephen Cagle
fonte
fonte
Respostas:
Não há suporte de linguagem para referências fracas em JavaScript. Você pode fazer o seu próprio usando a contagem de referência manual, mas não de maneira especialmente suave. Você não pode fazer um objeto proxy wrapper, porque em JavaScript os objetos nunca sabem quando estão prestes a ser coletados como lixo.
Assim, sua 'referência fraca' se torna uma chave (por exemplo, inteiro) em uma pesquisa simples, com um método de adicionar referência e remover referência, e quando não há mais referências manualmente rastreadas, a entrada pode ser excluída, deixando pesquisas futuras em essa chave para retornar nulo.
Este não é realmente um fraco ref, mas pode resolver alguns dos mesmos problemas. Normalmente é feito em aplicativos da web complexos para evitar vazamento de memória de navegadores (normalmente IE, especialmente em versões mais antigas) quando há um loop de referência entre um nó DOM ou manipulador de eventos e um objeto associado a ele, como um encerramento. Nestes casos, um esquema completo de contagem de referência pode nem mesmo ser necessário.
fonte
Ao executar JS no NodeJS, você pode considerar https://github.com/TooTallNate/node-weak .
fonte
Atualização: setembro de 2019
Não é possível usar referências fracas ainda, mas provavelmente em breve será possível, pois WeakRefs em JavaScript são Work In Progress. Detalhes abaixo.
Proposta
A proposta está agora no Estágio 3, o que significa que possui especificações completas e que mais refinamento exigirá feedback das implementações e dos usuários.
A proposta WeakRef engloba duas novas peças principais de funcionalidade:
Casos de uso
Um uso principal para referências fracas é implementar caches ou mapeamentos contendo objetos grandes, onde é desejável que um objeto grande não seja mantido vivo apenas porque aparece em um cache ou mapeamento.
A finalização é a execução de código para limpar após um objeto que se tornou inacessível para execução do programa. Os finalizadores definidos pelo usuário permitem vários novos casos de uso e podem ajudar a evitar vazamentos de memória ao gerenciar recursos que o coletor de lixo não conhece.
Fonte e outras leituras
https://github.com/tc39/proposal-weakrefs
https://v8.dev/features/weak-references
fonte
Referências realmente fracas, não, ainda não (mas os fabricantes de navegadores estão olhando para o assunto). Mas aqui está uma ideia de como simular referências fracas.
Você pode construir um cache através do qual você dirige seus objetos. Quando um objeto é armazenado, o cache mantém uma previsão de quanta memória o objeto ocupará. Para alguns itens, como armazenamento de imagens, isso é fácil de resolver. Para outros, isso seria mais difícil.
Quando você precisa de um objeto, solicita-o ao cache. Se o cache tiver o objeto, ele será retornado. Se não estiver lá, o item será gerado, armazenado e devolvido.
As referências fracas são simuladas pela remoção de itens de cache, quando a quantidade total de memória prevista atinge um determinado nível. Ele vai prever quais itens são menos usados com base na frequência com que são recuperados, ponderada por quanto tempo atrás foram retirados. Um custo de 'cálculo' também pode ser adicionado, se o código que cria o item for passado para o cache como um fechamento. Isso permitiria que o cache mantenha itens que são muito caros para construir ou gerar.
O algoritmo de exclusão é fundamental, porque se você errar, poderá acabar removendo os itens mais populares. Isso causaria um desempenho terrível.
Contanto que o cache seja o único objeto com referências permanentes aos objetos armazenados, o sistema acima deve funcionar muito bem como uma alternativa às verdadeiras referências fracas.
fonte
Somente para referência; JavaScript não tem, mas o ActionScript 3 (que também é ECMAScript) tem. Verifique o parâmetro do construtor para Dicionário .
fonte
Usar um mecanismo de cache para emular uma referência fraca, como JL235 sugerido acima , é razoável. Se referências fracas existissem nativamente, você observaria um comportamento como este:
Já com um cache, você observaria:
Como detentor de uma referência, você não deve fazer suposições sobre quando se refere a um valor, isso não é diferente usando um cache
fonte
Finalmente eles estão aqui. Ainda não implementado em navegadores, mas logo será.
https://v8.dev/features/weak-references
fonte
EcmaScript 6 (ES Harmony) tem um objeto WeakMap . O suporte do navegador entre os navegadores modernos é muito bom (as últimas 3 versões do Firefox, Chrome e até uma próxima versão do IE o suportam).
fonte
WeakMap
não fornece referências fracas para objetos - não são os valores que são referências fracas no WeakMap, mas as chaves . O fato de existirem referências fracas no mapa é apenas um mecanismo de prevenção de vazamento de memória e, de outra forma, não pode ser observado pelo usuário.weakmap.get(new String('any possible key that has ever existed or ever will exist'))
irá sempre serundefined
. Não é útil. Votação negativa!http://www.jibbering.com/faq/faq_notes/closures.html
ECMAScript usa coleta de lixo automática. A especificação não define os detalhes, deixando isso para os implementadores resolverem, e algumas implementações são conhecidas por dar uma prioridade muito baixa às suas operações de coleta de lixo. Mas a ideia geral é que se um objeto se tornar não referenciável (por não ter referências remanescentes a ele deixadas acessíveis para a execução do código), ele se torna disponível para coleta de lixo e em algum ponto futuro será destruído e quaisquer recursos que esteja consumindo serão liberados e retornados ao sistema para reutilização.
Isso normalmente seria o caso ao sair de um contexto de execução. A estrutura da cadeia de escopo, o objeto Ativação / Variável e quaisquer objetos criados dentro do contexto de execução, incluindo objetos de função, não seriam mais acessíveis e, portanto, ficariam disponíveis para a coleta de lixo.
O que significa que não há fracos, apenas aqueles que não estão mais disponíveis.
fonte