首页 > 解决方案 > IIFE:如果我返回警报而不将其包装在函数中,为什么我的代码会忽略 addEventListener?

问题描述

我很困惑为什么我必须将警报包装在一个函数中以避免我的代码忽略事件侦听器。

如果我运行此代码,它将正常工作,我将能够单击并在单击后显示警报

    elem.addEventListener('click', (function(numCopy) {
    return function() {
        alert(numCopy);
    };
})(num));

但是,如果我运行此代码,它将忽略事件侦听器并在页面加载后立即显示警报

elem.addEventListener('click', (function(numCopy) {
return alert(numCopy);
})(num));

我可以忽略它并接受这是它的完成方式,但如果有人能解释这背后的逻辑,我将非常感激,这样我就可以完全掌握这个概念,非常感谢。

标签: javascriptclosuresiife

解决方案


让我们通过查看以下示例来弄清楚发生了什么:

function foo(x) {
  return x;
}

var bar = foo(42);
baz(bar);

传递给的值是baz什么?42因为foo只是返回传递给它的值。

现在让我们内联函数调用

function foo(x) {
  return x;
}

baz(foo(42));

baz传递给这里的值是什么?尽管如此42,我们是否将返回值分配给变量或直接将其传递给其他函数并没有什么区别。

现在让我们内联函数定义

baz(function foo(x) { return x; }(42));

现在我们有一个IIFEbaz传递给这里的值是什么?还是42。我们实际上并没有改变代码在做什么,我们只是去掉了中间变量赋值(我们也可以foo从函数表达式中删除)。


这与您的代码有何关系?让我们从您的代码向后工作。我们从:

elem.addEventListener('click', (function(numCopy) {
   return alert(numCopy);
})(num));

让我们提取函数定义:

function foo(numCopy) {
  return alert(numCopy);
}

elem.addEventListener('click', foo(num));

现在让我们提取函数调用:

function foo(numCopy) {
  return alert(numCopy);
}

var bar = foo(num);
elem.addEventListener('click', bar);

你知道这里有什么问题吗?您正在调用该函数(foo在这种情况下)。该函数执行alert,这就是您立即看到警报的原因。

foo返回alert( 分配给的返回值bar),因此您将该值传递给addEventListener.

但是alert返回undefinedaddEventListener期望被传递一个函数。

这就是你的 IIFE 需要返回一个函数的原因。


推荐阅读