You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

import与require行为差异原因:为何变量更新结果不一致?

ES模块与CommonJS模块的行为差异原因解析

ES模块测试代码

test.js

// test.js file;
let k = 0;
let set = () => {
    k = 1;
};
export { k, set };

test1.js

// test1.js
import { k, set } from './test.js';

set();
console.log(k); // --> k = 1;

CommonJS模块测试代码

test.js

// test.js
let k = 0;
let set = () => {
    k = 1;
};
module.exports = { k, set };

test1.js

// test1.js
let { k, set } = require('./test.js');

set();
console.log(k); // --> k = 0;

差异原因解析

两种模块规范的核心区别在于导出值的引用逻辑:

  • ES模块:采用实时绑定机制,import导入的变量不是值的拷贝,而是直接指向模块内部的原始变量。调用set()修改模块内的k后,导入的k会同步更新,所以最终打印结果为1。

  • CommonJS模块:module.exports导出的是一个对象,对象里的k是模块内部变量k的值拷贝。当你用解构赋值let { k, set } = require('./test.js')时,当前模块的k已经是独立的副本,后续set()修改的是模块内部的原始k,不会影响这个副本,所以打印结果还是0。

如果想在CommonJS里实现和ES模块一致的效果,有两种方式:

  1. 给导出对象添加getter,实时返回内部变量值:
// 修改CommonJS的test.js
let k = 0;
let set = () => {
    k = 1;
};
module.exports = {
    get k() { return k; },
    set
};
  1. 不使用解构,直接保留模块引用:
// 修改CommonJS的test1.js
const mod = require('./test.js');
mod.set();
console.log(mod.k); // --> k = 1;

内容的提问来源于stack exchange,提问作者Haydar C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:44:54