Considere el siguiente ejemplo:
// module.mjs export let member = "initial" setTimeout(() => { member = "mutated" }, 2000) // index.mjs import { member } from "./module.mjs" setInterval(() => { console.log(member) }, 300); Si ejecuta index.mjs , imprime "initial" varias veces y después del tiempo de espera de 2 segundos comienza a imprimir "mutated" .
Esto es sorprendente para mí. Esperaba que siguiera imprimiendo "initial" ya que la referencia al member ha cambiado. No me sorprendería si mi index.mjs se viera así
// index.mjs import * as allExports from "./module.mjs" setInterval(() => { console.log(allExports.member) }, 300); La referencia a allExports no ha cambiado. Entonces, al acceder al member como una propiedad, tengo acceso a la nueva referencia. Y bastante justo, esto produce el mismo resultado.
Pero, ¿por qué funciona también en el primer caso? ¿Se actualizan las referencias de importación cada vez que se construye el contexto para una llamada de función? Bueno, entonces también debería funcionar con exportaciones predeterminadas. Sin embargo, después de ajustar el código de esta manera:
// module.mjs let member = "initial" export default member setTimeout(() => { member = "mutated" }, 2000) // index.mjs import member from "./module.mjs" setInterval(() => { console.log(member) }, 300); index.mjs sigue imprimiendo "initial" según mi intuición. Hmm, tal vez haya una diferencia fundamental entre las exportaciones predeterminadas y las exportaciones con nombre. ¿Qué pasa si hago esto?
// module.mjs export let member = "initial" setTimeout(() => { member = "mutated" }, 2000) // index.mjs import * as allExports from "./module.mjs" let { member } = allExports setInterval(() => { console.log(member) }, 300); Wow, sigue imprimiendo "initial" . Aquí es donde me confundí mucho. siempre supuse que
import { member } from "./module.mjs" es simplemente la abreviatura de importar todas named-exports como un objeto y luego hacer la desestructuración.
Entonces mi pregunta es: ¿qué principio subyacente justifica este comportamiento único de named-exports ?
La razón de esto es que técnicamente los módulos ES6 exportan e importan enlaces y no valores. Cuando tu lo hagas:
export let test = 0 Debe pensar que está exportando test no 0 . Eso significa que cualquier cambio en la variable se reflejará en sus importaciones.
La razón por la que esto sigue imprimiendo initial :
// index.mjs import * as allExports from "./module.mjs" let { member } = allExports setInterval(() => { console.log(member) }, 300); Es porque allExports es un objeto especial . Está creando un nuevo enlace aquí y el valor se copia, pero está perdiendo el enlace importado.