为什么导入模块修改导出变量后,该变量值未发生改变?
为什么导入模块修改导出变量后,该变量值未发生改变?
这个问题我之前也碰到过,本质是JavaScript模块导出的机制问题,尤其是原始类型和引用类型的区别,我给你拆解下:
首先看你的代码逻辑:你在register.ts里定义了原始类型的变量appUrl(初始是空字符串),然后导出它,同时在bootFunc里给它赋值新的字符串。但其他模块导入appUrl后,拿到的始终是空字符串,这是因为:
- 当其他模块
import { appUrl } from './register.ts'时,对于原始类型(字符串、数字、布尔等),JavaScript会把变量的当前值做一份值拷贝,存到导入模块的作用域里。简单说,其他模块拿到的只是初始空字符串的副本,和原模块里的appUrl已经是两个独立的变量了。 - 你在
bootFunc里执行appUrl = app.config.globalProperties.$appUrl时,只是把原模块里的appUrl变量重新指向了一个新的字符串值,但其他模块里已经导入的那个副本不会跟着更新——因为它们本来就不是同一个东西。
那怎么解决这个问题呢?给你两个常用方案:
方案一:用对象包裹值(引用类型传递)
把appUrl放到一个对象里,因为对象是引用类型,导出对象后,其他模块拿到的是对象的引用,修改对象的属性会同步到所有引用它的地方:
let appConfig = { url: '' }; const bootFunc = ({app, store, router}) => { console.log('In app-extension boot file'); appConfig.url = app.config.globalProperties.$appUrl; }; export {bootFunc as default, appConfig };
其他模块导入后,通过appConfig.url就能获取到最新的地址了。
方案二:用getter函数获取最新值
导出一个函数,每次调用这个函数时,返回原模块里appUrl的当前值:
let appUrl = ''; const bootFunc = ({app, store, router}) => { console.log('In app-extension boot file'); appUrl = app.config.globalProperties.$appUrl; }; const getAppUrl = () => appUrl; export {bootFunc as default, getAppUrl };
其他模块需要用的时候,调用getAppUrl()就能拿到最新的appUrl值。
总结一下:原始类型变量导出后是值拷贝,后续修改原变量不影响已导入的副本;而引用类型(对象、数组)导出的是引用,修改内部属性会同步,或者用函数动态获取最新值,就能解决你碰到的问题啦。
备注:内容来源于stack exchange,提问作者Bizmarck
相关产品推荐
相关产品推荐

