Вызов функции внутри IIFE - PullRequest
       27

Вызов функции внутри IIFE

1 голос
/ 28 сентября 2019

У меня есть следующий код:

function doStuff() {
    var increaseNumber = 0;

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

    return doSomeStuff();
};

doStuff();

Когда функция «doStuff» выполняется, функция «doSomeStuff», которая находится внутри функции «doStuff», запускается через «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 и увеличивает переменную увеличивается на 1 каждый раз, когда вызывается с помощью doStuff (). Когда я меняю «return doSomeStuff;» на «return doSomeStuff ();», код больше не работает так, как изложено.

Когда:

    return doSomeStuff();
})();

//doStuff();

IIFE и «doSomeStuff» выполняются один раз, а IncreaseNumber = 1. Дальнейший вызов IIFE через «doStuff ()» не работает из-за ошибки: «Ошибка JavaScript: doStuff не является функцией».

В основном я не понимаю здесь две вещи:

  1. Почему код работает, когда «return doSomeStuff;».Я не вижу, как эта функция запуска «doSomeStuff», так как () отсутствует.Когда я вызываю функцию, я обязательно добавляю ().Вот как я это узнал.
  2. ВЫШЕ ВСЕ: Почему я не могу вызвать «doStuff» как функцию, когда меняю «return doSomeStuff;» на «return doSomeStuff ();»?

Вы заметите, что я все еще новичок в Javascript.Я надеюсь, что я не повторяю здесь вопрос (честно говоря, я не смог найти в поиске или в Google ничего, что могло бы ответить на мой запрос).

Спасибо миллион за любые подсказки.

Ответы [ 4 ]

2 голосов
/ 28 сентября 2019

В этом коде IIFE хранится в переменной «doStuff»

Нет, IIFE запускается немедленно, а его возвращаемое значение сохраняется в doStuff.Поэтому, если вы хотите, чтобы doStuff была функцией, которую вы можете вызывать несколько раз, вам нужно вернуть функцию.

Почему код работает, когда «return doSomeStuff;».Я не вижу, как эта функция запуска «doSomeStuff», так как () отсутствует.

Он не будет вызывать doSomeStuff, сам по себе.Код внутри IIFE просто пытается создать функцию, а не запустить ее.Место, где вы вызываете функцию, это () в конце doStuff().

Почему я не могу вызвать «doStuff» как функцию, когда я изменяю «return doSomeStuff;» на «return doSomeStuff ();»? *

Потому что в этом случаеваш IIFE возвращает номер, а затем этот номер присваивается doStuff.

1 голос
/ 28 сентября 2019

Вот как это работает.

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: Опять же, давайте разберем это, чтобы лучше понять, что происходит подhood.

  1. Объявлена ​​переменная doStuff.
  2. При запуске IIFE вызывает функцию doSomeStuff.Поскольку doSomeStuff явно ничего не возвращает, движок JavaScript предполагает, что он возвращает undefined.Поэтому doStuff теперь содержит значение undefined.
  3. Поскольку undefined не является функцией и, следовательно, не вызывается, вы получите ошибку времени выполнения uncaught TypeError: doStuff is not a function.

Надеюсь, это поможет.

1 голос
/ 28 сентября 2019

В JavaScript return func(); возвращает значение, которое возвращается func().С другой стороны, return func; возвращает function, что само по себе возвращает значение, возвращаемое function func.Оба это разные вещи.return func возвращает функциональный объект.В JavaScript функции рассматриваются как объекты.return func вернет объект вызываемой функции.Возвращение func() возвращает значение, возвращаемое вызываемой функцией.

1 голос
/ 28 сентября 2019

В функциях 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()

...