【问题标题】:Calling function inside IIFE在 IIFE 中调用函数
【发布时间】:2019-09-28 14:05:28
【问题描述】:

我有以下代码:

function doStuff() {
    var increaseNumber = 0;

    function doSomeStuff() {
        console.log(++increaseNumber);
    }

    return doSomeStuff();
};

doStuff();

当执行函数“doStuff”时,函数“doStuff”内部的函数“doSomeStuff”通过“return doSomeStuff()”被触发,并且每次调用变量“increaseNumber”时都会增加1。如果我改变“return doSomeStuff();”要“return doSomeStuff;”,通过“doStuff()”调用“doStuff”是行不通的,正如我所假设的那样。

此外,我有以下代码,它产生与前面代码相同的结果:

var doStuff = (function () {
    var increaseNumber = 0;

    function doSomeStuff() {
        console.log(++increaseNumber);
    }

    return doSomeStuff;
})();

doStuff();

在此代码中,IIFE 存储在变量“doStuff”中。在 IIFE 中,存储了函数“doSomeStuff”,并且显然是通过“return doSomeStuff”触发的,并且每次通过“doStuff()”调用变量“increaseNumber”时都会增加 1。 当我更改“return doSomeStuff;”时到“return doSomeStuff();”,代码不再按布局工作。

时间:

    return doSomeStuff();
})();

//doStuff();

IIFE 和“doSomeStuff”执行一次,并且 increaseNumber = 1。通过“doStuff()”进一步调用 IIFE 不起作用,因为错误:“JavaScript 错误:doStuff 不是函数”。

这里主要有两点不明白:

  1. 为什么当“return doSomeStuff;”时代码可以工作。我看不出这是如何触发函数“doSomeStuff”的,因为缺少 ()。当我调用一个函数时,我确保添加 ()。我就是这么学的。
  2. 高于一切:为什么当我更改“return doSomeStuff;”时不能将“doStuff”作为函数调用要“返回 doSomeStuff();”?

你会注意到我还是一个 Javascript 新手。我希望我不会在这里重复一个问题(老实说,我无法通过搜索或在 Google 上找到任何可以回答我的问题的内容)。

感谢一百万的任何提示。

【问题讨论】:

    标签: javascript iife


    【解决方案1】:

    在此代码中,IIFE 存储在变量“doStuff”中

    不,IIFE 立即运行,其返回值 存储在doStuff 中。所以如果你想让doStuff成为一个可以多次调用的函数,你需要返回一个函数。

    为什么当“return doSomeStuff;”时代码可以工作。我看不出这是如何触发函数“doSomeStuff”的,因为缺少 ()。

    它不会触发 doSomeStuff,不会单独触发。 IIFE 中的代码只是试图创建函数,而不是实际运行它。调用函数的位置是doStuff() 末尾的()

    为什么当我更改“return doSomeStuff;”时不能将“doStuff”作为函数调用“返回 doSomeStuff();”?

    因为在这种情况下,您的 IIFE 会返回一个数字,然后将该数字分配给 doStuff

    【讨论】:

    • 恰到好处的答案触及了我一直在努力解决的问题:如果你想使用一个将 IIFE 存储为函数的变量,它实际上需要返回一个函数。并且“doSomeStuff”实际上不是由“return doSomeStuff”触发,而是由IIFE末尾的()触发。这一切都清楚了。
    【解决方案2】:

    在 Javascript 中,函数就像任何其他对象一样,我们可以从另一个函数返回一个函数,它们可以作为参数传递给其他函数等。

    当您return doSomeStuff; 时,您正在返回该函数。

    当您return doSomeStuff(); 时,您正在返回调用 doSomeStuff 函数返回的值。和

    一样
        var result = doSomeStuff();
        return result;
    

    现在回答问题。

    1. Why does the code work when “return doSomeStuff;”. I don’t see how this triggers function “doSomeStuff”, as the () is missing. When I call a function, I make sure to add (). That’s how I learned it.

    如上所述,您在此处返回函数,该函数存储到 var doStuff。当你执行doStuff()

    2. ABOVE EVERYTHING: Why can I not call “doStuff” as a function when I change “return doSomeStuff;” to “return doSomeStuff();”?

    如果您更改为return doSomeStuff();,您将不再返回函数,而是返回由doSomeStuff 函数返回的值并存储到var doStuff。你只能在函数上做(),因为doStuff不是函数你不能做doStuff()

    【讨论】:

      【解决方案3】:

      在 JavaScript 中,return func(); 返回由 func() 返回的值。另一方面,return func; 返回一个function,它本身返回由function func 返回的值。两者是两种不同的东西。 return func 返回一个函数对象。在 javascript 中,函数被视为对象。 return func 将返回可调用函数对象。返回 func() 返回可调用函数返回的值。

      【讨论】:

        【解决方案4】:

        这是它的工作原理。

        Q1(改写):“为什么会这样?”

        var doStuff = (function () {
          var increaseNumber = 0;
        
          function doSomeStuff() {
            console.log(++increaseNumber);
          }
        
          return doSomeStuff;
        })();
        
        doStuff();
        

        A1:让我们将其分解为简单的步骤。

        1. 已声明变量doStuff
        2. IIFE 运行,返回函数声明 doSomeStuff,它被分配给变量 doStuff
        3. 由于变量doStuff 现在包含一个函数,因此您可以像调用普通函数一样调用它。

        请注意,一旦 IIFE 完成,变量 increaseNumber 仍然被封闭在其内部范围内,并且可以被函数 doSomeStuff 访问。这个内部作用域在doSomeStuff 的生命周期内不会被破坏,现在分配给doStuff;这就是为什么调用 doStuff() 会产生预期效果的原因,即每次执行函数时,console.log 都会输出一个数字增量。

        Q2(改写):“为什么我不能将 doStuff 作为函数调用?”

        var doStuff = (function () {
          var increaseNumber = 0;
        
          function doSomeStuff() {
            console.log(++increaseNumber);
          }
        
          return doSomeStuff();
        })();
        
        doStuff();
        

        A2:再一次,让我们分解一下,以便更好地了解幕后发生的事情。

        1. 已声明变量doStuff
        2. 当 IIFE 运行时,调用函数doSomeStuff。由于doSomeStuff 没有显式返回任何内容,JavaScript 引擎假定它返回undefined。所以doStuff 现在的值是undefined
        3. 由于undefined 不是函数,因此不可调用,您将收到运行时错误uncaught TypeError: doStuff is not a function

        希望对你有帮助。

        【讨论】:

          猜你喜欢
          • 2018-05-30
          • 2021-04-24
          • 2016-12-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-05
          • 1970-01-01
          • 2016-01-19
          相关资源
          最近更新 更多