ES6 命名导出和默认导出之间的可变差异
Mutable difference between ES6 named and default exports
当 importing/exporting 来自 ES6 模块的数据时,该数据的可变性在命名导入和导出之间似乎有所不同。这是有原因的还是我不理解的一些根本差异?
// counter.js
export let count = 0;
export const incrementCount = () => count += 1;
export default count;
// main-default.js
import count, { incrementCount } from './counter';
console.log(count); // 0
incrementCount();
incrementCount();
console.log(count); // 0
// main-named.js
import { count, incrementCount } from './counter';
console.log(count); // 0
incrementCount();
incrementCount();
console.log(count); // 2
在这两种情况下,我都希望 count
增加。但是,这仅在使用命名导出时发生。
这是因为计数是数字而不是对象。通过导入默认值,您将计数值分配给新变量。通过命名导入,您可以像对象一样只读复制。
考虑一下:
// counter.js
export let count = {a:0};
export const incrementCount = () => count.a += 1;
export default (function(){ return count.a})();
当你运行:
// main-default.js
import countdefault, { count, incrementCount } from './counter.mjs';
console.log(countdefault, count);
incrementCount();
incrementCount();
console.log(countdefault, count);
你得到:
0 { a: 0 }
0 {一:2}
但是当您将计数器导出更改为对象时:
// counter.js
export let count = {a:0};
export const incrementCount = () => count.a += 1;
export default (function(){ return count})();
你得到:
{ a: 0 } { a: 0 }
{ a: 2 } { a: 2 }
问题是您使用了 export default count;
,它不导出 count
绑定(允许通过导入为可变变量取别名),但实际上创建了一个新的隐藏变量,该变量获取初始值已分配但之后永远不会更改的值。
export default count;
脱糖为
let *default* = count; // where *default* is a guaranteed collision-free identifier
export { *default* as default }
你想要的是
// counter.js
let count = 0;
export const incrementCount = () => count += 1;
export { count as default }
// main-default.js
import countA, { default as countB, incrementCount } from './counter';
console.log(countA, countB); // 0, 0
incrementCount();
console.log(countA, countB); // 1, 1
另见 。
当 importing/exporting 来自 ES6 模块的数据时,该数据的可变性在命名导入和导出之间似乎有所不同。这是有原因的还是我不理解的一些根本差异?
// counter.js
export let count = 0;
export const incrementCount = () => count += 1;
export default count;
// main-default.js
import count, { incrementCount } from './counter';
console.log(count); // 0
incrementCount();
incrementCount();
console.log(count); // 0
// main-named.js
import { count, incrementCount } from './counter';
console.log(count); // 0
incrementCount();
incrementCount();
console.log(count); // 2
在这两种情况下,我都希望 count
增加。但是,这仅在使用命名导出时发生。
这是因为计数是数字而不是对象。通过导入默认值,您将计数值分配给新变量。通过命名导入,您可以像对象一样只读复制。 考虑一下:
// counter.js
export let count = {a:0};
export const incrementCount = () => count.a += 1;
export default (function(){ return count.a})();
当你运行:
// main-default.js
import countdefault, { count, incrementCount } from './counter.mjs';
console.log(countdefault, count);
incrementCount();
incrementCount();
console.log(countdefault, count);
你得到:
0 { a: 0 }
0 {一:2}
但是当您将计数器导出更改为对象时:
// counter.js
export let count = {a:0};
export const incrementCount = () => count.a += 1;
export default (function(){ return count})();
你得到:
{ a: 0 } { a: 0 }
{ a: 2 } { a: 2 }
问题是您使用了 export default count;
,它不导出 count
绑定(允许通过导入为可变变量取别名),但实际上创建了一个新的隐藏变量,该变量获取初始值已分配但之后永远不会更改的值。
export default count;
脱糖为
let *default* = count; // where *default* is a guaranteed collision-free identifier
export { *default* as default }
你想要的是
// counter.js
let count = 0;
export const incrementCount = () => count += 1;
export { count as default }
// main-default.js
import countA, { default as countB, incrementCount } from './counter';
console.log(countA, countB); // 0, 0
incrementCount();
console.log(countA, countB); // 1, 1
另见