es6和commonjs对导入导出的值修改是否影响原模块

本文对比了ES6和CommonJS模块导出时,基本类型和引用类型数据的处理差异。ES6的导出是引用,实时同步变化,而CommonJS导出值拷贝,基本类型不受影响,引用类型修改可见。通过实例展示了这两种模式下修改行为和结果的不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

都说es6的导出是引用,commonjs导出是值拷贝,所以我想测试一下:

commonjs

commonjs对引用类型导出:对导出的引用修改,会改变模块的值,且引用了该模块的模块都可以获取最新值

// a.js
module.exports.x = "default1";
setTimeout(() => {
  module.exports.x = 6;
}, 4000);
setInterval(() => {
  console.log('a',module.exports);
}, 1000);

// b.js
let a = require("./a.js");
setInterval(() => {
  console.log('b',a);
}, 1000);
setTimeout(() => {
  a.x = "2";
}, 2000);

结果为:

a { x: 'default1' }
b { x: 'default1' }
a { x: '2' }
b { x: '2' }
a { x: '2' }
b { x: '2' }
a { x: 6 }
b { x: 6 }

commonjs对基本数据类型导出:外部修改无效(会脱离指向),内部的修改,无法反映到外部!

// a.js
module.exports = "default1";
setTimeout(() => {
  module.exports = 6;
}, 4000);
setInterval(() => {
  console.log('a',module.exports);
}, 1000);

// b.js
let a = require("./a.js");
setInterval(() => {
  console.log('b',a);
}, 1000);

结果为:

a default1
b default1
a default1
b default1
a default1
b default1
a 6
b default1

es6

对于es6导出的引用类型数据,任何一个地方的更改都会影响别的地方的数据!

// a.js
let x = {name:"default1"};
export let y = {name:"default2"};
export default x;
setTimeout(() => {
  x.name = "4";
  y.name = "4";
}, 4000);
setInterval(() => console.log("a", x, y), 1000);

// b.js
import x from "./a.js";
import { y } from "./a.js";
setInterval(() => console.log("b", x, y), 1000);
setTimeout(() => {
  x.name = "2";
  y.name = "2";
}, 2000);

结果:

a {name: 'default1'} {name: 'default2'}
b {name: 'default1'} {name: 'default2'}
a {name: 'default1'} {name: 'default2'}
b {name: 'default1'} {name: 'default2'}
a {name: '2'} {name: '2'}
b {name: '2'} {name: '2'}
a {name: '4'} {name: '4'}
b {name: '4'} {name: '4'}

换成基本类型数据,测试结果:无法在外部改变引入模块的值,因为是只读属性引入的,但是内部改变后可以被外部非默认导出获取到最新值!

// a.js
let x = 'default1';
export let y = 'default1';
export default x;
setTimeout(() => {
  x = "4";
  y = "4";
}, 4000);
setInterval(() => console.log("a", x, y), 1000);

// b.js
import x from "./a.js";
import { y } from "./a.js";
setInterval(() => console.log("b", x, y), 1000);
setTimeout(() => {
  x = "2"; // 报错!提示常量无法赋值
  y = "2"; // 报错!提示常量无法赋值
}, 2000);

结果:

a default1 default1
b default1 default1
a default1 default1
b default1 default1
报错了。。。
a default1 default1
b default1 default1
a 4 4
b default1 4

总结


  • 在模块导出基本类型数据时,require方式无法获取内部最新数据而且修改变量值会脱钩,import方式外部无法修改模块的数据(只读),但是非默认导出属性可以获取内部最新值。
  • 在模块导出引用类型数据时,外部和内部的修改都可以被观测到!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值