简体   繁体   English

在 IIFE 内部调用 function

[英]Calling function inside IIFE

I have the following code:我有以下代码:

function doStuff() {
    var increaseNumber = 0;

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

    return doSomeStuff();
};

doStuff();

When function “doStuff” is executed, function “doSomeStuff”, which is inside function “doStuff”, gets triggered via “return doSomeStuff()” and increments variable “increaseNumber” by 1 each time it is called. When function “doStuff” is executed, function “doSomeStuff”, which is inside function “doStuff”, gets triggered via “return doSomeStuff()” and increments variable “increaseNumber” by 1 each time it is called. If I change “return doSomeStuff();”如果我改变“return doSomeStuff();” to “return doSomeStuff;”, calling “doStuff” via “doStuff()” doesn't work, as I'd assume.到“return doSomeStuff;”,通过“doStuff()”调用“doStuff”不起作用,正如我所假设的那样。

Furthermore, I have the following code which yields the same result as the previous code:此外,我有以下代码,它产生与前面代码相同的结果:

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

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

    return doSomeStuff;
})();

doStuff();

In this code, an IIFE is stored inside variable “doStuff”.在此代码中,IIFE 存储在变量“doStuff”中。 Inside the IIFE, function “doSomeStuff” is stored and apparently gets triggered via “return doSomeStuff” and increments variable “increaseNumber” by 1 each time it is called via “doStuff()”.在 IIFE 内部,存储了 function “doSomeStuff”,显然是通过“return doSomeStuff”触发的,并且每次通过“doStuff()”调用变量“increaseNumber”时都会增加 1。 When I change “return doSomeStuff;”当我改变“return doSomeStuff;” to “return doSomeStuff();”, the code doesn't work as laid out anymore.到“return doSomeStuff();”,代码不再按规定工作。

When:什么时候:

    return doSomeStuff();
})();

//doStuff();

the IIFE and “doSomeStuff” are executed once and increaseNumber is = 1. Calling the IIFE further times via “doStuff()” doesn't work, because of error: “JavaScript error: doStuff is not a function”. IIFE 和“doSomeStuff”执行一次,并且 increaseNumber = 1。通过“doStuff()”进一步调用 IIFE 不起作用,因为错误:“JavaScript 错误:doStuff 不是函数”。

There are mostly two things that I don't understand here:这里主要有两件事我不明白:

  1. Why does the code work when “return doSomeStuff;”.为什么当“return doSomeStuff;”时代码有效。 I don't see how this triggers function “doSomeStuff”, as the () is missing.我看不出这是如何触发 function “doSomeStuff”的,因为缺少 ()。 When I call a function, I make sure to add ().当我调用 function 时,我确保添加 ()。 That's how I learned it.我就是这样学会的。
  2. ABOVE EVERYTHING: Why can I not call “doStuff” as a function when I change “return doSomeStuff;”最重要的是:当我更改“return doSomeStuff;”时,为什么不能将“doStuff”称为 function to “return doSomeStuff();”? “返回 doSomeStuff();”?

You will notice that I'm still a Javascript novice rather.你会注意到我还是一个 Javascript 新手。 I hope I'm not repeating a question here (I honestly couldn't find anything via search or on Google which would answer my query).我希望我不会在这里重复一个问题(老实说,我无法通过搜索或在 Google 上找到任何可以回答我查询的内容)。

Thanks a million for any hints.感谢一百万的任何提示。

In this code, an IIFE is stored inside variable “doStuff”在此代码中,IIFE 存储在变量“doStuff”中

No, the IIFE is run immediately, and its return value is stored in doStuff .不,IIFE 立即运行,其返回值存储在doStuff中。 So if you want doStuff to be a function that you can call multiple times, you need to return a function.因此,如果您希望doStuff成为可以多次调用的 function,则需要返回 function。

Why does the code work when “return doSomeStuff;”.为什么当“return doSomeStuff;”时代码有效。 I don't see how this triggers function “doSomeStuff”, as the () is missing.我看不出这是如何触发 function “doSomeStuff”的,因为缺少 ()。

It's not going to trigger doSomeStuff, not on its own.它不会触发 doSomeStuff,而不是单独触发。 The code inside the IIFE is just trying to create the function, not actually run it. IIFE 中的代码只是试图创建function,而不是实际运行它。 The spot where you call the function is the () at the end of doStuff() .您调用 function 的位置是doStuff() ()

Why can I not call “doStuff” as a function when I change “return doSomeStuff;”为什么当我更改“return doSomeStuff;”时不能将“doStuff”称为 function to “return doSomeStuff();”? “返回 doSomeStuff();”?

Because in that case, your IIFE is returning a number, and then that number gets assigned to doStuff .因为在这种情况下,您的 IIFE 将返回一个数字,然后将该数字分配给doStuff

In Javascript functions are just like any other objects, we can return a function from another function, they can be passed as arguments to other functions etc. In Javascript functions are just like any other objects, we can return a function from another function, they can be passed as arguments to other functions etc.

When you return doSomeStuff;当你return doSomeStuff; you are returning the function.您将返回 function。

When you return doSomeStuff();当你return doSomeStuff(); you are returning the value returned by invoking doSomeStuff function.您正在返回通过调用 doSomeStuff function 返回的值。 It is same as它与

    var result = doSomeStuff();
    return result;

Now to answer the questions.现在来回答问题。

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.

As mentioned above you are returning the function here, Which gets stored to var doStuff .如上所述,您在这里返回 function ,它被存储到var doStuff And it gets executed when you do doStuff()当你做doStuff()时它会被执行

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

If you change to return doSomeStuff();如果更改为return doSomeStuff(); you are not returning function anymore, instead you are returning the value returned by doSomeStuff function and gets stored to var doStuff .您不再返回 function ,而是返回doSomeStuff返回的值并存储到var doStuff You can do () only on functions, since doStuff is not function you cant do doStuff()您只能对函数执行() ,因为doStuff不是 function 您不能执行doStuff()

In JavaScript return func();在 JavaScript return func(); returns the value which is returned by func() .返回由func()返回的值。 On the other hand return func;另一方面return func; returns a function , that itself returns the value returned by the function func .返回一个function ,它本身返回function func返回的值。 Both are two different things.两者是两种不同的东西。 return func returns a function object. return func返回 function object。 In javascript functions are treated as objects.在 javascript 中,函数被视为对象。 return func will return the callable function object. return func将返回可调用的 function object。 Returning func() returns the value returned by the callable function.返回func()返回由可调用 function 返回的值。

Here is how it works.下面是它的工作原理。

Q1 (rephrased): "Why does this work?" Q1(改写):“为什么会这样?”

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

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

  return doSomeStuff;
})();

doStuff();

A1: Let's break it down to simple steps. A1:让我们把它分解成简单的步骤。

  1. The variable doStuff is declared.声明了变量doStuff
  2. The IIFE runs, returning the function declaration doSomeStuff , which gets assigned to the variable doStuff . IIFE 运行,返回 function 声明doSomeStuff ,它被分配给变量doStuff
  3. Since the variable doStuff now holds a function, you can call it as you would call a normal function.由于变量doStuff现在包含 function,因此您可以像调用普通 function 一样调用它。

Please note, the once the IIFE has finished, the variable increaseNumber remains enclosed in its inner scope and is accessible to the function doSomeStuff .请注意,一旦 IIFE 完成,变量increaseNumber仍然包含在其内部 scope 中,并且doSomeStuff可以访问。 This inner scope doesn't get destroyed for the lifetime of doSomeStuff , which is now assigned to doStuff ;这个内部doSomeStuff在 doSomeStuff 的生命周期内不会被破坏,现在分配给doStuff This is why calling doStuff() leads to the desired effect, ie console.log outputs a number increment every time the function gets executed.这就是为什么调用doStuff()会导致预期的效果,即每次执行 function 时, console.log都会输出一个数字增量。

Q2 (rephrased): "Why can't I call doStuff as a function?" Q2(改写):“为什么我不能将doStuff称为 function?”

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

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

  return doSomeStuff();
})();

doStuff();

A2: Again, let's break it down to better understand what happens under the hood. A2:再一次,让我们分解它以更好地了解幕后发生的事情。

  1. The variable doStuff is declared.声明了变量doStuff
  2. When the IIFE runs, is calls the function doSomeStuff .当 IIFE 运行时,调用doSomeStuff Since doSomeStuff does not explicitly return anything, the JavaScript engine assumes it returns undefined .由于doSomeStuff没有显式返回任何内容,因此 JavaScript 引擎假定它返回undefined So doStuff now holds a value of undefined .所以doStuff现在拥有一个undefined的值。
  3. Since undefined is not a function and is therefore not callable, you will get a runtime error uncaught TypeError: doStuff is not a function .由于undefined不是 function 并且因此不可调用,因此您将收到运行时错误uncaught TypeError: doStuff is not a function

Hope it helps.希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM