前言
面试时被问到esmoudle和commonjs导出数据修改后会如何输出,当时由于紧张没答上来,现在记录下。
Commonjs修改导出值
导出值是基础类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| let data = 1 const plusData = () => { data++ console.log(data) } module.exports = { data, plusData }
const { data, plusData } = require('./a.cjs');
plusData(); console.log(data);
data++ console.log(data);
data = 100; console.log(data);
plusData(); console.log(data);
|
导出值是引用类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const data = {a: 1} const plusData = () => { data.a++ console.log(data.a) } module.exports = { data, plusData }
let { data, plusData } = require('./a.cjs');
plusData(); console.log(data.a);
data.a++; console.log(data.a);
data = { a: 100 }; console.log(data.a);
plusData(); console.log(data.a);
|
ESmodule
导出值是基础类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| let data = 1 const plusData = () => { data++ console.log(data) } export default { data, plusData }
import a from './a.js'; let { data, plusData } = a; plusData(); console.log(data);
data.a++; console.log(data);
data = 5; console.log(data);
plusData(); console.log(data);
|
导出值是引用类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const data = {a: 1} const plusData = () => { data.a++ console.log(data.a) } export default { data, plusData }
import a from './a.js'; let { data, plusData } = a;
plusData(); console.log(data);
data.a++; console.log(data);
data = {a: 100}; console.log(data);
plusData(); console.log(data);
|
总结
导出的是基础类型
- ESM在调用方法修改模块中的值后,引用这个值的地方也随着改变;而CJS在调用方法后,并没有随着改变;就是因为CJS输出的是一个值的拷贝,而ESM输出的是值的引用;
- 不管是esm还是cjs如果直接修改导出值则内外会失去关联,此时外部修改不会影响内部
导出的值是引用类型
- 不管是esm还是cjs导出引用类型内外部修改都会对原值有影响
- 不管是esm还是cjs如果直接修改导出值则内外会失去关联,此时外部修改不会影响内部