¿Hay alguna forma en JavaScript para crear una "referencia débil" a otro objeto? Aquí está la página wiki que describe qué es una referencia débil. Aquí hay otro artículo que los describe en Java. ¿Alguien puede pensar en una forma de implementar este comportamiento en javascript?
javascript
weak-references
Stephen Cagle
fuente
fuente
Respuestas:
No hay soporte de idioma para las referencias débiles en JavaScript. Puede rodar el suyo utilizando el recuento manual de referencias, pero no de forma especialmente fluida. No puede crear un objeto contenedor de proxy, porque en JavaScript, los objetos nunca saben cuándo están a punto de ser recolectados como basura.
Entonces, su 'referencia débil' se convierte en una clave (por ejemplo, un número entero) en una búsqueda simple, con un método de agregar referencia y eliminar referencia, y cuando ya no hay referencias rastreadas manualmente, la entrada se puede eliminar, dejando futuras búsquedas en esa clave para devolver nulo.
Esto no es realmente una referencia débil, pero puede resolver algunos de los mismos problemas. Por lo general, se realiza en aplicaciones web complejas para evitar la pérdida de memoria de los navegadores (generalmente IE, especialmente versiones anteriores) cuando hay un bucle de referencia entre un Nodo DOM o controlador de eventos y un objeto asociado con él, como un cierre. En estos casos, es posible que ni siquiera sea necesario un sistema completo de recuento de referencias.
fuente
Al ejecutar JS en NodeJS, puede considerar https://github.com/TooTallNate/node-weak .
fuente
Actualización: septiembre de 2019
No es posible usar referencias débiles todavía, pero lo más probable es que pronto sea posible, ya que WeakRefs en JavaScript están en proceso. Detalles abajo.
Propuesta
La propuesta está ahora en la Etapa 3, lo que significa que tiene una especificación completa y que un mayor refinamiento requerirá comentarios de las implementaciones y los usuarios.
La propuesta de WeakRef abarca dos nuevas funciones importantes:
Casos de uso
Un uso principal de las referencias débiles es implementar cachés o mapeos que contienen objetos grandes, donde se desea que un objeto grande no se mantenga vivo únicamente porque aparece en un caché o mapeo.
La finalización es la ejecución de código para limpiar después de un objeto que se ha vuelto inalcanzable para la ejecución del programa. Los finalizadores definidos por el usuario permiten varios casos de uso nuevos y pueden ayudar a prevenir pérdidas de memoria al administrar recursos que el recolector de basura no conoce.
Fuente y lectura adicional
https://github.com/tc39/proposal-weakrefs
https://v8.dev/features/weak-references
fuente
Verdaderas referencias débiles, no, todavía no (pero los fabricantes de navegadores están analizando el tema). Pero aquí hay una idea sobre cómo simular referencias débiles.
Podría crear un caché a través del cual conducir sus objetos. Cuando se almacena un objeto, la caché mantiene una predicción de cuánta memoria ocupará el objeto. Para algunos elementos, como el almacenamiento de imágenes, esto es sencillo de resolver. Para otros, esto sería más difícil.
Cuando necesite un objeto, solicítelo al caché. Si la caché tiene el objeto, se devuelve. Si no está allí, el elemento se genera, se almacena y luego se devuelve.
Las referencias débiles se simulan mediante la eliminación de elementos de la memoria caché, cuando la cantidad total de memoria prevista alcanza un cierto nivel. Predecirá qué elementos se utilizan menos en función de la frecuencia con la que se recuperan, ponderado por cuánto tiempo se retiraron. También se podría agregar un costo de 'cálculo', si el código que crea el artículo se pasa a la caché como un cierre. Esto permitiría que la caché guarde elementos que son muy costosos de construir o generar.
El algoritmo de eliminación es clave, porque si se equivoca, podría terminar eliminando los elementos más populares. Esto causaría un rendimiento terrible.
Siempre que el caché sea el único objeto con referencias permanentes a los objetos almacenados, entonces el sistema anterior debería funcionar bastante bien como una alternativa a las verdaderas referencias débiles.
fuente
Solo para referencia; JavaScript no lo tiene, pero ActionScript 3 (que también es ECMAScript) sí. Consulte el parámetro de constructor para Dictionary .
fuente
Es razonable usar un mecanismo de almacenamiento en caché para emular una referencia débil, como sugirió JL235 anteriormente . Si las referencias débiles existieran de forma nativa, observaría un comportamiento como este:
Mientras que con un caché observaría:
Como titular de una referencia, no debe hacer suposiciones sobre cuándo se refiere a un valor, esto no es diferente al usar un caché
fuente
Finalmente están aquí. Aún no implementado en los navegadores, pero pronto lo estará.
https://v8.dev/features/weak-references
fuente
EcmaScript 6 (ES Harmony) tiene un objeto WeakMap . El soporte del navegador entre los navegadores modernos es bastante bueno (las últimas 3 versiones de Firefox, Chrome e incluso una próxima versión de IE lo admiten).
fuente
WeakMap
no da referencias débiles a objetos; no son los valores los que son referencias débiles en WeakMap, sino las claves . El hecho de que existan referencias débiles en el mapa es solo un mecanismo de prevención de fugas de memoria y no es observable para el usuario de otra manera.weakmap.get(new String('any possible key that has ever existed or ever will exist'))
que siempre lo seráundefined
. No es útil. ¡Votar en contra!http://www.jibbering.com/faq/faq_notes/closures.html
ECMAScript utiliza la recolección automática de basura. La especificación no define los detalles, dejando que los implementadores lo resuelvan, y se sabe que algunas implementaciones dan una prioridad muy baja a sus operaciones de recolección de basura. Pero la idea general es que si un objeto se vuelve irreferible (al no tener referencias restantes a él accesibles para ejecutar el código), estará disponible para la recolección de basura y en algún momento futuro será destruido y cualquier recurso que esté consumiendo será liberado y devuelto. al sistema para su reutilización.
Este sería normalmente el caso al salir de un contexto de ejecución. La estructura de la cadena de alcance, el objeto Activación / Variable y cualquier objeto creado dentro del contexto de ejecución, incluidos los objetos de función, ya no serán accesibles y, por lo tanto, estarán disponibles para la recolección de basura.
Lo que significa que no hay débiles, solo los que ya no están disponibles.
fuente