ES6 命名导出和默认导出之间的可变差异

Joh*_*ain 6 javascript ecmascript-6 es6-modules

从 ES6 模块导入/导出数据时,数据的可变性在命名导入和导出之间似乎不同。是否有原因或我不理解的一些根本区别?

// counter.js
export let count = 0;

export const incrementCount = () => count += 1;

export default count;
Run Code Online (Sandbox Code Playgroud)
// main-default.js
import count, { incrementCount } from './counter';

console.log(count); // 0

incrementCount();
incrementCount();

console.log(count); // 0
Run Code Online (Sandbox Code Playgroud)
// main-named.js
import { count, incrementCount } from './counter';

console.log(count); // 0

incrementCount();
incrementCount();

console.log(count); // 2
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我都希望count增加。但是,这仅在使用命名导出时发生。

Ber*_*rgi 6

问题是您使用了export default count;,它不会导出count绑定(允许通过导入对可变变量进行别名),但实际上创建了一个新的隐藏变量,该变量获得分配的初始值但之后永远不会更改。

export default count;
Run Code Online (Sandbox Code Playgroud)

脱糖

let *default* = count; // where *default* is a guaranteed collision-free identifier
export { *default* as default }
Run Code Online (Sandbox Code Playgroud)

你想要的是

// counter.js
let count = 0;
export const incrementCount = () => count += 1;
export { count as default }
Run Code Online (Sandbox Code Playgroud)

// main-default.js
import countA, { default as countB, incrementCount } from './counter';

console.log(countA, countB); // 0, 0
incrementCount();
console.log(countA, countB); // 1, 1
Run Code Online (Sandbox Code Playgroud)

另请参阅如何在 Javascript 中为默认导入设置别名?.


小智 -4

这是因为计数是数字而不是对象。通过导入默认值,您可以将计数值分配给新变量。通过命名导入,您可以像对象一样只读复制。考虑一下:

// counter.js
export let count = {a:0};
export const incrementCount = () => count.a += 1;
export default (function(){ return count.a})();
Run Code Online (Sandbox Code Playgroud)

当你跑步时:

// main-default.js
import countdefault, { count, incrementCount } from './counter.mjs';
console.log(countdefault, count);
incrementCount();
incrementCount();
console.log(countdefault, count);
Run Code Online (Sandbox Code Playgroud)

你得到:

0 {一:0}

0 {一:2}

但是当您将计数器导出更改为对象时:

// counter.js
export let count = {a:0};
export const incrementCount = () => count.a += 1;
export default (function(){ return count})();
Run Code Online (Sandbox Code Playgroud)

你得到:

{ 一:0 } { 一:0 }

{ 一:2 } { 一:2 }