Comprender las referencias débiles en JavaScript

 

 

 

  • Patrones de diseño de interfaces inteligentes, vídeo de 10h + formación UX
  • SmashingConf Friburgo 2024

  • Índice
    1. Referencia débil
    2. Referencia fuerte
    3. Recolección de basura en JavaScript
      1. Accesibilidad
    4. Comparación de conjunto y conjunto débil
    5. Comparación de mapas y mapas débiles
    6. Áreas de aplicación de WeakMap
      1. Almacenamiento en caché
      2. Datos adicionales
    7. Conclusión

    En este artículo, Frank Joseph explica las referencias fuertes y débiles en JavaScript, así como el concepto de accesibilidad. ¡Vamos a profundizar en!

     

    La gestión de la memoria y el rendimiento son aspectos importantes del desarrollo de software y a los que todo desarrollador de software debe prestar atención. Aunque son útiles, las referencias débiles no se utilizan con frecuencia en JavaScript. WeakSety WeakMapconocieron JavaScript en la versión ES6.

    Referencia débil

    Para aclarar, a diferencia de la referencia fuerte, la referencia débil no impide que el recolector de basura reclame o recopile el objeto al que se hace referencia, incluso si es la única referencia al objeto en la memoria.

    Antes de entrar en referencias fuertes, WeakSet, Set, WeakMapy Map, ilustremos la referencia débil con el siguiente fragmento:

    // Create an instance of the WeakMap object.let human = new WeakMap():// Create an object, and assign it to a variable called man.let man = { name: "Joe Doe" };// Call the set method on human, and pass two arguments (key and value) to it.human.set(man, "done")console.log(human)

    El resultado del código anterior sería el siguiente:

    WeakMap {{…} = 'done'}man = null;console.log(human)

    El manargumento ahora está establecido en el WeakMapobjeto. En el momento en que reasignamos la manvariable a null, la única referencia al objeto original en la memoria era la referencia débil, y provenía del WeakMapque creamos anteriormente. Cuando el motor JavaScript ejecuta un proceso de recolección de basura, el manobjeto se eliminará de la memoria y de la WeakMapque le asignamos. Esto se debe a que es una referencia débil y no impide la recolección de basura.

     

    Parece que estamos progresando. Hablemos de referencias fuertes y luego uniremos todo.

    Referencia fuerte

    Una referencia fuerte en JavaScript es una referencia que evita que un objeto sea recolectado como basura. Mantiene el objeto en la memoria.

    Los siguientes fragmentos de código ilustran el concepto de referencia fuerte:

    let man = {name: "Joe Doe"};let human = [man];man = null;console.log(human);

    El resultado del código anterior sería este:

    // An array of objects of length 1. [{…}]

    Ya no se puede acceder al objeto a través de la dogvariable debido a la fuerte referencia que existe entre la humanmatriz y el objeto. El objeto se retiene en la memoria y se puede acceder a él con el siguiente código:

    console.log(human[0])

    El punto importante a tener en cuenta aquí es que una referencia débil no impide que un objeto sea recolectado como basura, mientras que una referencia fuerte sí previene que un objeto sea recolectado como basura.

    Recolección de basura en JavaScript

    Como en todo lenguaje de programación, la gestión de la memoria es un factor clave a considerar al escribir JavaScript. A diferencia de C, JavaScript es un lenguaje de programación de alto nivel que asigna memoria automáticamente cuando se crean objetos y que la borra automáticamente cuando los objetos ya no son necesarios. El proceso de borrar la memoria cuando los objetos ya no se utilizan se conoce como recolección de basura. Es casi imposible hablar de recolección de basura en JavaScript sin tocar el concepto de accesibilidad.

    Accesibilidad

    Todos los valores que están dentro de un alcance específico o que están en uso dentro de un alcance se consideran "alcanzables" dentro de ese alcance y se denominan "valores alcanzables". Los valores alcanzables siempre se almacenan en la memoria.

    Los valores se consideran alcanzables si son:

    • valores en la raíz del programa o referenciados desde la raíz, como variables globales o la función que se está ejecutando actualmente, su contexto y devolución de llamada;
    • valores accesibles desde la raíz mediante una referencia o cadena de referencias (por ejemplo, un objeto en la variable global que hace referencia a otro objeto, que también hace referencia a otro objeto; todos estos se consideran valores alcanzables).

    Los fragmentos de código siguientes ilustran el concepto de accesibilidad:

    let languages = {name: “JavaScript”};

    Aquí tenemos un objeto con un par clave-valor (con el nombre JavaScript) que hace referencia a la variable global languages. Si sobrescribimos el valor de languagesasignándole null

    languages = null;

    … entonces el objeto será recolectado como basura y JavaScriptno se podrá volver a acceder al valor. Aquí hay otro ejemplo:

    let languages = {name: “JavaScript”};let programmer = languages;

    A partir de los fragmentos de código anteriores, podemos acceder a la propiedad del objeto tanto desde la languagesvariable como desde la programmervariable. Sin embargo, si nos ponemos languagesa null

     

    languages = null;

    … entonces el objeto todavía estará en la memoria porque se puede acceder a él a través de la programmervariable. Así es en pocas palabras cómo funciona la recolección de basura.

    Nota: De forma predeterminada, JavaScript utiliza referencias sólidas para sus referencias. Para implementar una referencia débil en JavaScript, usaría WeakMap, WeakSeto WeakRef.

    Comparación de conjunto y conjunto débil

    Un objeto establecido es una colección de valores únicos con una sola aparición. Un conjunto, como una matriz, no tiene un par clave-valor. Podemos iterar a través de un conjunto de matrices con los métodos de matriz for… ofy .forEach.

    Ilustremos esto con los siguientes fragmentos:

    let setArray = new Set(["Joseph", "Frank", "John", "Davies"]);for (let names of setArray){ console.log(names)}// Joseph Frank John Davies

    .forEachTambién podemos usar el iterador:

     setArray.forEach((name, nameAgain, setArray) ={ console.log(names); });

    A WeakSetes una colección de objetos únicos. Como sugiere el nombre, WeakSetlos s utilizan referencias débiles. Las siguientes son propiedades de WeakSet():

    • Sólo puede contener objetos.
    • Se puede acceder a los objetos dentro del conjunto en otro lugar.
    • No se puede recorrer en bucle.
    • Me gusta Set(), WeakSet()tiene los métodos add, hasy delete.

    El siguiente código ilustra cómo utilizarlo WeakSet()y algunos de los métodos disponibles: Korean Beauty

    const human = new WeakSet();let paul = {name: "Paul"};let mary = {gender: "Mary"};// Add the human with the name paul to the classroom. const classroom = human.add(paul);console.log(classroom.has(paul)); // truepaul = null;// The classroom will be cleaned automatically of the human paul.console.log(classroom.has(paul)); // false

    En la línea 1, hemos creado una instancia de WeakSet(). En las líneas 3 y 4, creamos objetos y los asignamos a sus respectivas variables. En la línea 7, agregamos pauly WeakSet()lo asignamos a la classroomvariable. En la línea 11 hicimos la paulreferencia null. El código de la línea 15 regresa falseporque WeakSet()se limpiará automáticamente; por lo tanto, WeakSet()no impide la recolección de basura.

    Comparación de mapas y mapas débiles

    Como sabemos por la sección anterior sobre recolección de basura, el motor JavaScript mantiene un valor en la memoria siempre que sea accesible. Ilustremos esto con algunos fragmentos:

    let smashing = {name: "magazine"};// The object can be accessed from the reference.// Overwrite the reference smashing.smashing = null;// The object can no longer be accessed.

    Las propiedades de una estructura de datos se consideran accesibles mientras la estructura de datos está en la memoria y, por lo general, se mantienen en la memoria. Si almacenamos un objeto en una matriz, mientras la matriz esté en la memoria, aún se puede acceder al objeto incluso si no tiene otras referencias.

     

    let smashing = {name: "magazine"};let arr = [smashing];// Overwrite the reference.smashing = null;console.log(array[0]) // {name: 'magazine'}

    Aún podemos acceder a este objeto incluso si la referencia se sobrescribió porque el objeto se guardó en la matriz; por lo tanto, se guardó en la memoria mientras la matriz todavía esté en la memoria. Por lo tanto, no fue recogido como basura. Como hemos usado una matriz en el ejemplo anterior, maptambién podemos usarla. Mientras maptodavía exista, los valores almacenados en él no serán recolectados como basura.

    let map = new Map();let smashing {name: "magazine"};map.set(smashing, "blog");// Overwrite the reference.smashing = null;// To access the object.console.log(map.keys());

    Como un objeto, maps puede contener pares clave-valor y podemos acceder al valor a través de la clave. Pero con maps, debemos usar el .get()método para acceder a los valores.

    Según Mozilla Developer Network, el Mapobjeto contiene pares clave-valor y recuerda el orden de inserción original de las claves. Cualquier valor (tanto objetos como valores primitivos ) se puede utilizar como clave o valor.

    A diferencia de a map, WeakMaptiene una referencia débil; por lo tanto, no impide que la recolección de basura elimine los valores a los que hace referencia si esos valores no están fuertemente referenciados en otro lugar. Aparte de esto, WeakMapes lo mismo que map. WeakMapLos s no son enumerables debido a referencias débiles.

    Con WeakMap, las claves deben ser objetos y los valores pueden ser un número o una cadena.

    Los fragmentos a continuación ilustran cómo WeakMapfunciona y los métodos que contiene:

    // Create a weakMap.let weakMap = new WeakMap();let weakMap2 = new WeakMap();// Create an object.let ob = {};// Use the set method.weakMap.set(ob, "Done");// You can set the value to be an object or even a function.weakMap.set(ob, ob)// You can set the value to undefined.weakMap.set(ob, undefined);// WeakMap can also be the value and the key.weakMap.set(weakMap2, weakMap)// To get values, use the get method.weakMap.get(ob) // Done// Use the has method.weakMap.has(ob) // trueweakMap.delete(ob)weakMap.has(ob) // false

    Un efecto secundario importante de usar objetos como claves en un WeakMapsin otras referencias es que se eliminarán automáticamente de la memoria durante la recolección de basura.

    Áreas de aplicación de WeakMap

    WeakMapSe puede utilizar en dos áreas del desarrollo web: almacenamiento en caché y almacenamiento de datos adicional.

    Almacenamiento en caché

    Esta es una técnica web que implica guardar (es decir, almacenar) una copia de un recurso determinado y devolverla cuando se solicite. El resultado de una función se puede almacenar en caché para que cada vez que se llame a la función, el resultado almacenado en caché se pueda reutilizar.

     

    Veamos esto en acción. Crea un archivo, nómbralo cachedResult.jsy escribe lo siguiente en él:

     let cachedResult = new WeakMap(); // A function that stores a result.function keep(obj){if(!cachedResult.has(obj){ let result = obj; cachedResult.set(obj, result); }return cachedResult.get(obj);}let obj = {name: "Frank"};let resultSaved = keep(obj)obj = null;// console.log(cachedResult.size); Possible with map, not with WeakMap

    Si hubiéramos usado Map()en lugar de WeakMap()en el código anterior y hubiera múltiples invocaciones en la función keep(), entonces solo calcularía el resultado la primera vez que se llamara y lo recuperaría de cachedResultlas otras veces. El efecto secundario es que necesitaremos limpiar cachedResultsiempre que el objeto no sea necesario. Con WeakMap(), el resultado almacenado en caché se eliminará automáticamente de la memoria tan pronto como se recolecte la basura del objeto. El almacenamiento en caché es un excelente medio para mejorar el rendimiento del software: podría ahorrar costos de uso de bases de datos, llamadas API de terceros y solicitudes de servidor a servidor. Con el almacenamiento en caché, se guarda localmente una copia del resultado de una solicitud.

    Datos adicionales

    Otro uso importante WeakMap()es el almacenamiento de datos adicional. Imagine que estamos construyendo una plataforma de comercio electrónico y tenemos un programa que cuenta a los visitantes y queremos poder reducir el recuento cuando los visitantes se van. Esta tarea sería muy exigente con Map, pero bastante fácil de implementar con WeakMap():

    let visitorCount = new WeakMap();function countCustomer(customer){ let count = visitorCount.get(customer) || 0; visitorCount.set(customer, count + 1);}

    Creemos un código de cliente para esto:

    let person = {name: "Frank"};// Taking count of person visit.countCustomer(person)// Person leaves.person = null;

    Con Map(), tendremos que limpiar visitorCountcada vez que se vaya un cliente; de lo contrario, crecerá en la memoria indefinidamente, ocupando espacio. Pero con WeakMap(), no necesitamos limpiar visitorCount; Tan pronto como una persona (objeto) se vuelve inalcanzable, se recolectará automáticamente como basura.

    Conclusión

    En este artículo, aprendimos sobre la referencia débil, la referencia fuerte y el concepto de accesibilidad, y tratamos de conectarlos con la gestión de la memoria lo mejor que pudimos. Espero que hayas encontrado valioso este artículo. No dudes en dejar un comentario.

    (il, al, yk)Explora más en

    • javascript
    • Actuación
    • Codificación





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Comprender las referencias débiles en JavaScript

    Comprender las referencias débiles en JavaScript

    Patrones de diseño de interfaces inteligentes, vídeo de 10h + formación UX SmashingConf Friburgo 2024 Índice

    programar

    es

    https://aprendeprogramando.es/static/images/programar-comprender-las-referencias-debiles-en-javascript-1144-0.jpg

    2024-04-04

     

    Comprender las referencias débiles en JavaScript
    Comprender las referencias débiles en JavaScript

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20