Что вернёт этот код: typeof (function(){})()

Дан блок кода:

console.log(typeof (function () {})())

Что выведет console.log?

Разбор по шагам

Рассматривается выражение typeof (function () {})().
Скобки вокруг function () {} делают запись функциональным выражением, а выражение можно сразу вызвать при помощи ().

Ключевой момент — порядок вычисления: вызов функции выполняется раньше, чем применяется унарный оператор typeof. Поэтому выражение группируется так:

typeof (function () {})()
// фактически группируется как:
typeof ( (function () {})() )

Далее вычисление можно разложить на шаги:

  1. Вызывается функция (function () {})().
  2. В теле функции нет return <значение>, значит результат вызова — undefined.
  3. Затем вычисляется typeof undefined, результат — строка "undefined".
  4. console.log(...) выводит эту строку в консоль.

Для наглядности:

ШагФрагментРезультат
1(function () {})()undefined
2typeof ((function () {})())"undefined"
3console.log("undefined")вывод в консоль

Теория: typeof и приоритет

typeof — унарный оператор, который возвращает строковое имя типа значения, полученного из операнда.
В выражениях JavaScript некоторые операции выполняются раньше других: вызов функции x(y) имеет более высокий приоритет, чем унарные операторы вроде typeof x.
Из‑за этого сначала вычисляется часть (...)(), и только потом typeof применяется к результату.

Если ошибочно прочитать выражение как (typeof (function () {}))(), то получится попытка вызвать строку (ведь typeof (function(){}) даёт "function"), а строка как функция не вызывается и это привело бы к ошибке времени выполнения. В данном коде этого не происходит, потому что фактически сначала выполняется вызов функции, а затем typeof.

Теория: вызов функции и undefined

Если функция завершилась без явного return <значение>, результат её вызова равен undefined.
Это справедливо и для функционального выражения, которое вызывается сразу после создания (часто такой приём используют, чтобы изолировать область видимости).

Примеры:

// Нет return со значением → undefined
function f() { }
console.log(f())              // undefined
console.log(typeof f())       // "undefined"

// Есть return → тип зависит от возвращаемого значения
function g() { return 123 }
console.log(g())              // 123
console.log(typeof g())       // "number"

Отдельно важно: запись function () {} без имени сама по себе не является допустимым объявлением функции в таком месте кода, поэтому для немедленного вызова применяется форма с группировкой: (function () {})().

Кратко: функция без return возвращает undefined, вызов выполняется раньше typeof, поэтому typeof видит undefined и превращает его в строку "undefined", которую и выводит console.log.