Почему мы не можем немедленно вызвать объявление функции? - PullRequest
1 голос
/ 18 октября 2019

Почему нам нужно написать выражение, которое оценивает тип функции, чтобы немедленно вызывать функцию? Почему мы не можем просто объявить функцию и сразу вызвать ее?

Почему

(function(){}()) or !function(){}()

И почему не просто

function(){}()

Это связано с тем, как вещи помещаются в память, я полагаю, но я изо всех сил пытаюсь найтиполный ответ.

Ответы [ 2 ]

7 голосов
/ 18 октября 2019

Поскольку при достижении окончательного } объявления функции интерпретатор видит все объявление функции, предшествующее ему, как одиночный оператор . Если вы ставите что-либо после }, это будет интерпретироваться как отдельное, неиспользуемое выражение:

function foo() {
}('bar')

Это создает строку bar, но интерпретатор с ней ничего не делает - это похоже на

function foo() {
}
'bar'

Строка объявлена, но нигде не используется.

Если вы ничего не помещаете в скобки, выдается ошибка SyntaxError, потому что интерпретаторожидание оператора или выражения, но только () не является ни тем, ни другим.

Это все равно, что помещать вещи после блока if. Независимо от того, что вы ставите после } блока if, последующее будет интерпретироваться как полностью автономное выражение / выражение:

if (true) {
  // do something
}'foo';

Здесь, как и в примере объявления функции, вы создаете строку, содержащую foo, но выражение не используется.

2 голосов
/ 18 октября 2019

Причина в том, что код ECMAScript обрабатывается.

Во время инициализации сначала обрабатываются объявления функций, а затем объявления переменных (процесс, часто называемый "подъем"). Затем начинается выполнение.

Выражения функций вычисляются во время выполнения.

Таким образом, вы не можете сразу выполнять объявления функций, потому что даже переменных еще не существует, а другой код, который функция может зависеть от hasnлибо не были выполнены.

Рассмотрим что-то простое:

foo(); // shows undefined

var randomNumber = function() { // function expression
  return Math.random();
}();  // () makes it an IIFE

foo(); // shows value assigned to randomNumber

function foo() {  // function declaration
  alert(randomNumber);
} 

Функция foo существует до randomNumber (несмотря на последовательностькод), поэтому попытка выполнить его немедленно приведет к ошибке ссылки. После завершения инициализации были объявлены foo и randomNumber .

Код RHS присвоения randomNumber анализируется во времяинициализация для синтаксических ошибок, но не выполняется до фазы выполнения.

Теперь начинается выполнение, выполняется выражение функции и присваивается значение randomNumber , поэтому, когда foo равно randomNumber существует и имеет любое значение, возвращаемое выражением функции в RHS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...