JavaScript插件中Reference Error问题求助及代码解析
关于JavaScript插件中Reference Error的问题解答
嘿,我来帮你拆解这个问题的原因,再给你靠谱的解决方案!
首先先把你的代码贴出来方便分析:
jQuery.fn.validate = function(options) { var _self = this; // 下方调用会触发Reference Error abc(); // 但在下方调用则正常 _self.on("submit", function(event) { abc(); // 正常工作 }); abc = function () { console.log('here'); }; };
为什么会出现这个差异?
这完全是代码执行顺序和函数/变量的提升规则在起作用:
- 当你在插件开头直接调用
abc()时,代码还没执行到abc = function () {...}这一行。而且你这里的abc没有用var/let/const声明,属于隐式全局变量,此时它根本还没被定义,自然会抛出Reference Error。 - 而
submit事件的回调函数是异步触发的——它不会在插件初始化阶段立刻运行,只有当用户实际提交表单时才会执行。到那个时候,整个插件函数里的代码已经跑完了,abc已经被赋值成对应的函数,所以调用就完全没问题了。
另外要提醒你:直接给未声明的变量赋值会造成全局污染,这是个不好的编码习惯,很容易和其他代码产生冲突,尽量避免。
如何解决开头调用初始化/重置函数的需求?
有两种简洁且规范的方式:
方式1:提前用函数声明定义(推荐)
函数声明会被JavaScript引擎自动提升到当前作用域的顶部,所以哪怕你把函数写在调用之后,也能正常执行,而且是局部函数,不会污染全局:
jQuery.fn.validate = function(options) { var _self = this; // 直接调用初始化/重置函数 initValidation(); resetValidation(); _self.on("submit", function(event) { initValidation(); // 事件回调里也能正常调用 }); // 用函数声明定义你的初始化/重置函数 function initValidation() { console.log('初始化校验逻辑'); } function resetValidation() { console.log('重置校验状态'); } };
方式2:提前声明变量并赋值函数表达式
如果你更习惯用函数表达式,那记得提前声明变量,再把函数赋值给它,确保调用时变量已经有值:
jQuery.fn.validate = function(options) { var _self = this; // 提前声明局部变量 var initValidation; // 先赋值函数 initValidation = function() { console.log('初始化校验逻辑'); }; // 现在可以安全调用了 initValidation(); _self.on("submit", function(event) { initValidation(); }); };
两种方式都能解决你的问题,其中方式1的函数声明写法更简洁,也更符合JavaScript的提升特性,是更推荐的方案。
内容的提问来源于stack exchange,提问作者Aman jaura
相关产品推荐
相关产品推荐

