从事件监听器调用自执行函数(IIFE)的实现问题排查
输入框事件绑定与初始化执行问题分析
背景铺垫
先明确现有代码和需求:
现有HTML代码:
<input id="target" type="number">
现有JavaScript代码:
var target = document.getElementById('target');
需求很清晰:
- 输入框内容变化时触发指定函数执行
- 页面加载完成后,通过自执行函数(IIFE)将该函数先执行一次
三种实现方案
下面列出三个实现示例,其中有一个无法满足需求:
方案1(完全正常)
target.addEventListener('input', myFunction); function myFunction(){ console.log('executed!'); } // 页面加载时用IIFE执行一次 (function(){ myFunction(); })();
函数声明会被JS自动提升到作用域顶部,所以事件绑定的时候myFunction已经存在,后续IIFE也能正常调用,完美匹配需求。
方案2(同样正常)
// 先定义函数 function myFunction(){ console.log('executed!'); } // 绑定输入事件 target.addEventListener('input', myFunction); // 直接调用实现初始化执行 myFunction();
逻辑直白易懂:先定义函数,再绑定事件,最后手动执行一次初始化,完全符合需求。
方案3(踩坑!无法正常工作)
target.addEventListener('input', myFunction); // 用函数表达式定义函数 var myFunction = function(){ console.log('executed!'); }; // IIFE尝试执行函数 (function(){ myFunction(); })();
方案3失效原因拆解
核心问题出在JS的变量提升机制:
- 用
var声明的变量会被提升到当前作用域顶部,但变量的赋值操作不会同步提升。 - 当代码执行到
target.addEventListener('input', myFunction);时,myFunction确实已经被声明了,但它的值还是undefined(赋值语句在后面),这时候事件绑定的其实是个“空值”,根本不是我们写的目标函数! - 后面的IIFE虽然能正常执行(此时
myFunction已经完成赋值),但输入框内容变化时,之前绑定的无效事件不会触发函数执行,等于事件绑定环节直接失效了。
简单说就是事件绑定的时机太早,绑了个不存在的函数上去,后续给变量赋值也救不回之前的错误绑定。
内容的提问来源于stack exchange,提问作者Jeweetzelf
相关产品推荐
相关产品推荐

