子模块调用父模块函数时提示parentFunction未定义的问题咨询
嗨,我来帮你捋捋这个问题哈~
你遇到的parentFunction is undefined报错,核心原因是作用域的封闭性:你把parentFunction定义在了一个立即执行函数表达式(IIFE)的内部,这个IIFE会创建一个独立的私有作用域,里面的函数和变量默认是对外不可见的——不管是父模块的其他部分,还是导入的子模块,都没法直接访问到它。
你可能误以为父模块里的函数能被子模块直接调用,但其实ES模块本身就有独立的模块作用域,再加上IIFE的私有作用域双重限制,childFunction自然找不到parentFunction啦。
接下来给你几个可行的解决办法,你可以根据场景选:
方法1:把parentFunction导出到模块作用域
如果希望parentFunction可以被其他模块直接调用,最简单的方式就是把它从IIFE里移出来,作为模块导出成员:
// 父模块代码 import {childFunction} from './child.js' // 导出parentFunction,让其他模块能导入 export function parentFunction(){ alert('parent hello'); } var parent = (function(){ // 内部依然可以正常调用parentFunction })();
然后在child.js里导入它再调用:
// child.js代码 import {parentFunction} from './父模块文件名.js' export function childFunction(){ alert('child hello'); parentFunction(); }
方法2:通过参数传递函数(更推荐,低耦合)
如果不想把parentFunction暴露给所有模块,只是让childFunction能调用它,最好的方式是调用childFunction时把函数作为参数传进去——这样模块间的耦合度更低,也更符合模块化的设计思路:
// 父模块代码 import {childFunction} from './child.js' var parent = (function(){ function parentFunction(){ alert('parent hello'); } // 调用childFunction时传入parentFunction childFunction(parentFunction); })();
// child.js代码 export function childFunction(parentFunc){ alert('child hello'); parentFunc(); // 调用传入的函数 }
方法3:挂载到全局作用域(不推荐)
如果你只是临时测试或者有特殊需求,也可以把parentFunction挂载到全局对象(比如浏览器里的window)上,但这种方式会污染全局作用域,容易引发变量冲突,不推荐在正式项目里用:
// 父模块代码 var parent = (function(){ function parentFunction(){ alert('parent hello'); } // 挂载到全局 window.parentFunction = parentFunction; })();
这样child.js里就能直接调用parentFunction()了。
总结一下:你不是用错了功能,而是对作用域的封闭性和模块间的访问规则理解有点偏差,只要通过上面的方式把parentFunction的作用域开放给子模块,就能解决问题啦~
备注:内容来源于stack exchange,提问作者user1835434

