Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutable difference between ES6 named and default exports

When importing/exporting data from ES6 modules, mutability of that data appears to be different between named imports and exports. Is there a reason for this or some fundamental difference I'm not understanding?

// 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

In both scenarios, I would expect count to increment. However, this only happens when using named exports.

like image 697
Johnny Crain Avatar asked Oct 17 '19 17:10

Johnny Crain


People also ask

What is the difference between named exports and default exports?

Exports without a default tag are Named exports. Exports with the default tag are Default exports. Using one over the other can have effects on your code readability, file structure, and component organization. Named and Default exports are not React-centric ideas.

What is export default in es6?

Export Default is used to export only one value from a file which can be a class, function, or object. The default export can be imported with any name.

What is difference between export default and export in react JS?

export { variable as default } exports the reference to the exported variable , whereas with export default variable , the importing modules do not receive the reference to the exported variable .

What is named export in JavaScript?

What are Named Exports? Named exports allow us to share multiple objects, functions or variables from a single file and were introduced with the release of ES2015. Named exports are imported with curly braces in various files and must be imported using the name of the object, function or variable that was exported.


1 Answers

The problem is that you used export default count;, which does not export the count binding (allowing aliasing the mutable variable by an import) but actually creates a new, hidden variable that gets the initial value assigned but is never changed afterwards.

export default count;

desugars to

let *default* = count; // where *default* is a guaranteed collision-free identifier
export { *default* as default }

What you want instead is

// 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

See also How can I alias a default import in Javascript?.

like image 76
Bergi Avatar answered Oct 19 '22 01:10

Bergi