ES Modules 的导出是绑定的、只读的实时引用,基本类型不可重赋值;可通过导出对象属性或 setter 函数实现可变性,动态 import() 不影响已有绑定。

ES Modules 的导出(export)是**绑定的、只读的实时引用**,不能直接“修改导出的数值”——尤其是基本类型(如 let count = 0 后 export { count }),外部模块即使能访问,也无法重新赋值给该导出名。但你可以通过设计让导出的值“可变”,关键在于:导出一个**可变的引用**(如对象、数组)或提供**修改方法**。
✅ 正确做法:导出对象属性(推荐)
基本类型导出后不可重赋值,但对象的属性可以随时修改:
// counter.js
export const state = {
count: 0,
name: 'app'
};
// ✅ 外部可修改:state.count++ 或 state.count = 5
其他模块导入后直接修改属性,所有模块看到的是同一份状态:
// main.js
import { state } from './counter.js';
state.count = 10; // ✅ 生效,所有导入 state 的地方都会看到更新
✅ 正确做法:导出 setter 函数
封装修改逻辑,更安全、可控:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
// counter.js
let _count = 0;
export const getCount = () => _count;
export const setCount = (value) => { _count = value; };
export const increment = () => _count++;
// 或导出命名空间对象
export const counter = {
get count() { return _count; },
set count(v) { _count = v; }
};
调用方使用函数修改,避免直接暴露变量:
import { setCount } from './counter.js'; setCount(42);import { counter } from './counter.js'; counter.count = 100;
❌ 常见误区:试图重赋值导出的变量
以下写法会报错(SyntaxError 或运行时错误):
// ❌ 错误:count 是只读绑定,不能重新赋值
export let count = 0;
// 在另一个模块中:
import { count } from './counter.js';
count = 5; // ? TypeError: Assignment to constant variable.(严格模式下)
即使用 var 或 let 导出,ESM 规范也禁止外部模块对导入的绑定执行赋值操作。
⚠️ 注意:动态 import() 不影响已有导出绑定
import('./module.js') 返回 Promise,用于按需加载模块,但它加载的是新模块实例(若非单例),不会“刷新”或“覆盖”已存在的导出绑定。想实现热更新或重置状态,需手动设计状态管理(如清空缓存、重建对象),而非依赖 ESM 机制。
不复杂但容易忽略:ESM 的“活绑定”只保证引用不变,不保证可写。让导出可变,靠的是导出引用类型或控制接口,而不是试图绕过模块系统的只读约束。

















