为什么JavaScript默认导出不具备实时绑定特性?
为什么默认导出不像具名导出那样具备实时绑定特性?
以下代码示例展示了该现象:
//------ lib.js ------ export let counter = 0; export function incCounter() { counter++; } export default counter; //------ main1.js ------ import { counter, incCounter } from "./lib"; import $counter from "./lib"; console.log({ $counter, counter }); // {$counter: 0, counter: 0} incCounter(); console.log({ $counter, counter }); // {$counter: 0, counter: 1}
上述代码显示,具名导出的counter具备实时绑定特性,但默认导出的$counter却没有,核心原因在于两者的导出逻辑本质不同:
- 具名导出是导出变量的绑定关系:
export let counter的作用是向外暴露counter变量的绑定,当你在main1.js中import { counter }时,拿到的是和lib.js里counter变量直接关联的引用。两边指向同一个绑定,所以incCounter修改原变量后,导入的counter会同步更新。 - 你写的默认导出是导出值的副本:
export default counter执行时,是把counter当前的数值(0)作为导出值,相当于直接导出了一个字面量0。此时main1.js里的$counter只是拿到了这个值的副本,和原变量counter没有绑定关联,后续原变量变化自然不会影响这个副本。
如果想让默认导出也具备实时绑定,需要把变量的绑定作为默认导出,修改lib.js的写法:
// lib.js export let counter = 0; export function incCounter() { counter++; } export { counter as default }; // 导出counter的绑定,而非当前值
这样修改后,main1.js中导入的$counter就会和原变量实时同步。
另外也可以通过导出引用类型(比如对象)或返回值的函数来实现类似效果:
// lib.js 方式1:导出包含counter的对象 export let counter = 0; export function incCounter() { counter++; } export default { get counter() { return counter } }; // main1.js 调用方式 console.log($counter.counter); // 实时获取最新值
// lib.js 方式2:导出返回counter的函数 export let counter = 0; export function incCounter() { counter++; } export default () => counter; // main1.js 调用方式 console.log($counter()); // 实时获取最新值
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

