为何事件处理程序中的立即调用函数会在事件触发前执行?
为什么事件处理程序里的立即调用函数会在事件触发前执行?
嘿,这个问题其实是因为你搞混了立即执行函数(IIFE)的执行时机和事件处理函数的触发逻辑,咱们一步步拆解来看:
先搞懂你的代码为什么会提前执行
先看这段代码:
let a = (function gigel() { alert("dd"); })();
这里的(function(){...})()就是立即执行函数的核心写法——定义完函数的瞬间就会调用它,所以当页面加载到这行代码的时候,不管你有没有点击按钮,这个alert("dd")都会立刻弹出来。而且因为这个函数没有返回任何值,变量a最后会变成undefined。
之后你给按钮绑定onclick="a",其实相当于点击按钮时尝试执行undefined,这当然不会有任何效果,因为undefined不是可执行的函数。
而你第二个按钮的写法<button onclick="alert('dd')">Click me</button>之所以正常,是因为浏览器只会在按钮被点击时,才会执行onclick属性里的代码片段,这才是符合你预期的“点击触发”逻辑。
怎么改成点击才执行的正确写法
如果你想让a成为点击时才触发的函数,有两种常见的正确写法:
方案1:直接赋值函数(不用立即执行)
把函数本身赋值给a,而不是执行后的结果:
let a = function gigel() { alert("dd"); };
然后按钮要写成这样(注意要加()调用函数):
<button onclick="a()">Click me</button>
方案2:用立即执行函数返回一个待触发的函数
如果需要在页面加载时做一些初始化操作,但把核心逻辑留到点击时执行,可以让IIFE返回一个函数:
let a = (function gigel() { // 这里放页面加载时要执行的初始化代码 console.log("页面加载完成,初始化完毕"); // 返回点击时要执行的函数 return function() { alert("dd"); }; })();
按钮同样写成:
<button onclick="a()">Click me</button>
这样页面加载时只会跑初始化代码,点击按钮才会弹出提示。
关键总结
- 立即执行函数末尾的
()就是用来立刻触发函数执行的,和事件完全无关,只要代码执行到这一行就会触发。 - 事件处理属性里需要的是可执行的代码,或者能被调用的函数引用,如果赋值的是函数执行后的结果(比如
undefined),点击时自然不会有反应。
内容的提问来源于stack exchange,提问作者Iannis Paris
相关产品推荐
相关产品推荐

