← Назад к вопросам

Почему typeof function выводит function?

2.0 Middle🔥 141 комментариев
#JavaScript Core#TypeScript

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Отличный вопрос! Он затрагивает не только особенности оператора typeof, но и саму природу функций в JavaScript — языке, где они являются объектами первого класса.

Суть ответа: особый случай в спецификации

Короткий ответ: потому что typeof — это не низкоуровневая инструкция, а оператор с определенным, четко прописанным в спецификации ECMAScript поведением. Для функций typeof специально возвращает строку "function", чтобы отличать вызываемые объекты (callable objects) от обычных.

Однако, чтобы понять, почему это важно и не является противоречием, нужно копнуть глубже.

Функция — это особый объект

С технической точки зрения, функция в JavaScript — это объект, наделенный внутренними свойствами [[Call]] и (опционально, для конструкторов) [[Construct]]. Именно наличие внутреннего свойства [[Call]] делает объект "вызываемым" (callable).

Давайте проверим это утверждение:

function sayHi() {
    console.log('Hi!');
}

// Функция ведет себя как объект:
sayHi.customProperty = 'I am a property!';
console.log(sayHi.customProperty); // 'I am a property!'
console.log(typeof sayHi); // "function"
console.log(sayHi instanceof Object); // true

Как видно, sayHi — это и функция (результат typeof), и объект (результат instanceof Object).

Логика оператора typeof

Согласно спецификации ECMAScript (на момент ES2023), алгоритм оператора typeof работает так:

  1. Если операнд — undefined, возвращает "undefined".
  2. Если операнд — null, возвращает "object" (историческая особенность, которую уже нельзя исправить).
  3. Если операнд — объект с внутренним свойством [[Call]] (т.е. функция), возвращает "function".
  4. Если операнд — любой другой объект (массив, дата, обычный объект, ошибка и т.д.), возвращает "object".
  5. Для всех остальных примитивных типов (boolean, number, string, symbol, bigint) возвращает соответствующую строку.

Таким образом, typeof — это не "детектор типа в памяти", а высокоуровневый оператор классификации значений, и для функций он делает особое исключение.

Практическая необходимость и наследие

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

Представьте мир, где typeof для функции возвращал бы "object":

// Как бы мы проверяли, что callback — это функция?
function dangerousOperation(callback) {
    // Плохая проверка:
    if (typeof callback === 'object') {
        // Здесь окажутся и объекты {}, и массивы [], и null!
        callback(); // Ошибка, если это не функция!
    }
}

// Хорошая проверка (в реальном мире):
function safeOperation(callback) {
    if (typeof callback === 'function') { // Спасибо особому поведению typeof!
        callback();
    } else {
        console.error('callback is not a function!');
    }
}

Важные нюансы и граничные случаи

  1. Стрелочные функции и классы: typeof также возвращает "function" для стрелочных функций и классов (классы технически являются функциями-конструкторами).

    const arrowFn = () => {};
    class MyClass {};
    console.log(typeof arrowFn); // "function"
    console.log(typeof MyClass); // "function"
    
  2. Объекты, имитирующие функции: Некоторые встроенные объекты, такие как RegExp, в очень старых браузерах (IE) могли возвращать "function" при typeof, но в современных реализациях это исправлено, и они корректно возвращают "object".

  3. Проверка через Object.prototype.toString: Более надежный способ получить точный тип — использовать Object.prototype.toString.call().

    Object.prototype.toString.call(function() {}); // "[object Function]"
    Object.prototype.toString.call([]);            // "[object Array]"
    Object.prototype.toString.call({});            // "[object Object]"
    

Вывод

Итак, typeof function выводит "function" не потому, что функция — это не объект, а потому, что оператор typeof был специально разработан для возврата этого значения для всех вызываемых объектов. Это решение, закрепленное в спецификации ECMAScript, является компромиссом между теоретической чистотой (все есть объект) и практической необходимостью (надежное различение вызываемых и невызываемых сущностей). Это один из краеугольных камней системы типов JavaScript, который делает язык одновременно гибким и (относительно) безопасным для динамической типизации.

Почему typeof function выводит function? | PrepBro