将代码包裹自调用函数后logIn函数无法调用的问题求助
问题原因与解决方案
你碰到的这个问题非常典型——自调用函数(IIFE)会创建一个独立的私有作用域,你定义的logIn函数现在被完全封闭在这个作用域内部,而按钮的onclick事件是在全局作用域下执行的,根本找不到这个函数,所以才会抛出"Uncaught ReferenceError: logIn is not defined"的错误。
简单来说:IIFE的核心作用就是隔离代码,避免变量/函数污染全局空间,但代价就是内部内容默认对外不可见,而你用onclick属性绑定事件的方式,本质是在全局环境里找logIn函数,自然找不到闭包里的它。
下面给你两种可行的解决方案:
方案1:将函数暴露到全局作用域
如果一定要保留onclick属性的写法,可以把logIn函数挂载到全局的window对象上,让外部能访问到它:
(function($) { const auth = firebase.auth(); // 将logIn挂载到window,使其成为全局可访问的函数 window.logIn = function(){ window.alert("pressed log in button"); var userEmail = document.getElementById("txtEmail").value; var userPass = document.getElementById("txtPassword").value; auth.signInWithEmailAndPassword(userEmail,userPass).catch(function(error) { var errorCode = error.code; var errorMessage = error.message; window.alert("Error : " + errorMessage); }); }; })(jQuery); // 注意这里要传入对应的$对象,比如jQuery,否则内部$会未定义
⚠️ 小提醒:这种方式会稍微打破IIFE的隔离性,但如果是必须全局访问的函数,这是最直接的解决办法。
方案2:在IIFE内部绑定事件(推荐)
更符合现代前端实践的方式是,放弃onclick属性,在IIFE内部通过事件监听器来绑定按钮的点击事件。这样既能保持作用域的隔离性,又能正确调用内部的logIn函数:
(function($) { const auth = firebase.auth(); // 先获取你的登录按钮(假设按钮的id是loginBtn) const loginButton = document.getElementById("loginBtn"); function logIn(){ window.alert("pressed log in button"); var userEmail = document.getElementById("txtEmail").value; var userPass = document.getElementById("txtPassword").value; auth.signInWithEmailAndPassword(userEmail,userPass).catch(function(error) { var errorCode = error.code; var errorMessage = error.message; window.alert("Error : " + errorMessage); }); }; // 在IIFE内部绑定点击事件,无需暴露logIn到全局 loginButton.addEventListener("click", logIn); })(jQuery);
这种方式不需要污染全局作用域,同时也避免了全局变量冲突的风险,是更推荐的写法。
另外还要注意:你原来的IIFE最后缺少了调用参数(比如(jQuery)),如果内部用到了$,一定要传入对应的对象,否则会导致$未定义的问题。
内容的提问来源于stack exchange,提问作者user11650277
相关产品推荐
相关产品推荐

