ES6 Modules命名空间冲突:如何获取元素原始与修改状态?
问题根源
你遇到的问题本质是ES模块的单例特性:ES模块在整个应用中只会被实例化一次,所有导入操作共享同一个模块实例。
具体来说,module01.js导出的element是一个DOM元素对象的引用,module02.js导入这个引用后修改了它的innerText属性——这直接修改了内存中的同一个对象。所以不管你从module01还是module02导入,拿到的都是同一个DOM元素,最终显示的自然是最后一次修改的结果。
解决方法
1. 工厂函数(推荐)
让module01导出一个创建元素的函数,而不是直接导出元素。每次调用函数都会生成一个全新的DOM元素,这样就能同时获取原始状态和修改后的状态:
module01.js
export function createModuleElement() { const element = document.createElement('div'); element.innerText = 'Module1'; return element; }
module02.js
import { createModuleElement } from './module1.js'; const element = createModuleElement(); element.innerText = 'Module2'; export { element as newElem };
script.js
import { createModuleElement } from './modules/module1.js'; import { newElem } from './modules/module2.js'; const container = document.createElement('div'); container.appendChild(createModuleElement()); // 原始状态:Module1 container.appendChild(newElem); // 修改后状态:Module2 document.body.appendChild(container);
2. 克隆DOM节点(非常规方案)
如果不想修改module01的导出逻辑,可以在module02里克隆原始元素的副本,保留原始状态,再修改原元素:
module02.js
import { element } from './module1.js'; // 克隆原始元素的副本,保留初始状态 const originalElement = element.cloneNode(true); // 修改原元素的内容 element.innerText = 'Module2'; export { originalElement, element as newElem };
script.js
import { originalElement, newElem } from './modules/module2.js'; const container = document.createElement('div'); container.appendChild(originalElement); // 显示Module1 container.appendChild(newElem); // 显示Module2 document.body.appendChild(container);
3. 动态导入(仅用于观察状态变化)
如果只是想在控制台打印原始和修改后的状态(而非同时显示在DOM),可以用动态导入延迟module02的加载时机:
script.js
import { element } from './modules/module1.js'; console.log('原始状态:', element.innerText); // 输出Module1 // 延迟加载module02,此时再修改元素 import('./modules/module2.js').then(({ newElem }) => { console.log('修改后状态:', newElem.innerText); // 输出Module2 });
注意:这种方法仍然是操作同一个DOM元素,无法同时在DOM中显示两个状态,仅适合观察状态变化的场景。
内容的提问来源于stack exchange,提问作者i5x
相关产品推荐
相关产品推荐

