admin管理员组文章数量:1414628
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.
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.
- For what it's worth, code above was tested after being transpiled with Babel 7.6.0. – Johnny Crain Commented Oct 17, 2019 at 17:08
- does the same thing happen without transpiling? – dandavis Commented Oct 17, 2019 at 17:12
- 1 @JohnnyCrain if you watch out the transpiled code carefully, the function changes the name export not the default exported count – Code Maniac Commented Oct 17, 2019 at 17:23
- @dandavis The result is the same whether transpiled or run directly by Chromium. – Johnny Crain Commented Oct 17, 2019 at 17:27
2 Answers
Reset to default 10The 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?.
It is because count is number not object. By importing default you are assigning value of count to new variable. By named import you have readonly copy like object. Consider this:
// counter.js
export let count = {a:0};
export const incrementCount = () => count.a += 1;
export default (function(){ return count.a})();
When you run:
// main-default.js
import countdefault, { count, incrementCount } from './counter.mjs';
console.log(countdefault, count);
incrementCount();
incrementCount();
console.log(countdefault, count);
you get:
0 { a: 0 }
0 { a: 2 }
but when you change counter export to object:
// counter.js
export let count = {a:0};
export const incrementCount = () => count.a += 1;
export default (function(){ return count})();
you get:
{ a: 0 } { a: 0 }
{ a: 2 } { a: 2 }
本文标签: javascriptMutable difference between ES6 named and default exportsStack Overflow
版权声明:本文标题:javascript - Mutable difference between ES6 named and default exports - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745190665a2646894.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论