从代码可维护性角度出发,命名导出比默认导出更好,因为它减少了因引用产生重命名情况的发生。
但命名导出与默认导出的区别不止如此,在逻辑上也有很大差异,为了减少开发时在这方面栽跟头,有必要提前了解它们的区别。
本周找来了这方面很好的的文章:export-default-thing-vs-thing-as-default,先描述梗概,再谈谈我的理解。
概述
一般我们认为,import 导入的是引用而不是值,也就是说,当导入对象在模块内值发生变化后,import 导入的对象值也应当同步变化。
// module.js
export let thing = 'initial';
setTimeout(() => {
thing = 'changed';
}, 500);
上面的例子,500ms 后修改导出对象的值。
// main.js
import { thing as importedThing } from './module.js';
const module = await import('./module.js');
let { thing } = await import('./module.js');
setTimeout(() => {
console.log(importedThing); // "changed"
console.log(module.thing); // "changed"
console.log(thing); // "initial"
}, 1000);
1s 后输出发现,前两种输出结果变了,第三种没有变。也就是对命名导出来说,前两种是引用,第三种是值。
但默认导出又不一样:
// module.js
let thing = 'initial';
export { thing };
export default thing;
setTimeout(() => {
thing = 'changed';
}, 500);
// main.js
import { thing, default as defaultThing } from './module.js';
import anotherDefaultThing from './module.js';
setTimeout(() => {
console.log(thing); // "changed"
console.log(defaultThing); // "initial"
console.log(anotherDefaultThing); // "initial"
}, 1000);
为什么对默认导出的导入结果是值而不是引用?
原因是默认导出可以看作一种对 “default 赋值” 的特例,就像 export default = thing 这种旧语法表达的一样,本质上是一种赋值,所以拿到的是值而不是引用。
那么默认导出的另一种写法 export { thing as default } 也是如此吗?并不是:
// module.js
let thing = 'initial';
export { thing, thing as default };
setTimeout(() => {
thing = 'changed';
}, 500);
// main.js
import { thing, default as defaultThing } from './module.js';
import anotherDefaultThing from './module.js';
setTimeout(() => {
console.log(thing); // "changed"
console.log(defaultThing); // "changed"
console.log(anotherDefaultThing); // "changed"
}, 1000);
可见,这种默认导出,导出的都是引用。所以导出是否是引用,不取决于是否是命名导出,而是取决于写法。不同的写法效果不同,哪怕相同含义的不同写法,效果也不同。
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h63785.shtml