Оператор typeof в JavaScript возвращает строку с названием типа значения: "number", "string", "boolean", "undefined", "bigint", "symbol", "object" или "function". Для чисел, строк и других примитивов результат точный, а null, массив и дата одинаково дают "object", и в этих случаях нужна другая проверка.
Все примеры запускались в Node.js 24.14. Результаты typeof задаёт спецификация ECMAScript, поэтому в браузере они те же.

- Синтаксис оператора typeof
- Восемь типов данных в JavaScript и результат typeof
- Почему typeof null возвращает object
- Массивы, даты и встроенные объекты
- typeof function, классы и async-функции
- typeof NaN: «не число» с типом number
- Необъявленная переменная и временная мёртвая зона
- Обёртки new String, new Number и new Boolean
- Преобразование типов и данные извне
- Функция, чтобы определить тип точнее
- Частые ошибки с typeof
- Сравнение с undefined без кавычек
- Забытые скобки вокруг выражения
- Частые вопросы
- Чем typeof отличается от instanceof?
- Работает ли typeof с BigInt и Symbol?
- Как проверить, что переменная строка?
- Что вернёт typeof для undefined?
Синтаксис оператора typeof
Пишется слово typeof, пробел и операнд: переменная, литерал или выражение. Скобки допустимы, но это обычная группировка, а не вызов функции, поэтому typeof(5) и typeof 5 работают одинаково:
console.log(typeof 5, typeof(5), typeof typeof 5); // number number string
Третий результат показывает, что typeof всегда возвращает строку. Значит, сравнивать его нужно со строкой в кавычках и в нижнем регистре: typeof x === "number".
Восемь типов данных в JavaScript и результат typeof
В спецификации JavaScript восемь типов: семь примитивных (undefined, null, boolean, number, bigint, string, symbol) и object. Сам примитив изменить нельзя, переменной можно только присвоить другое значение, а объект хранит набор свойств. Вот что typeof возвращает для каждого:
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof true); // boolean
console.log(typeof 42); // number
console.log(typeof 10n); // bigint
console.log(typeof "hello"); // string
console.log(typeof Symbol("id")); // symbol
console.log(typeof { name: "Аня" }); // object
console.log(typeof function () {}); // function
Строк девять, а разных результатов восемь: null и объект дают одинаковый "object", а функции получили свою строку.
| Тип данных | Пример значения | Что возвращает typeof |
|---|---|---|
| Undefined | undefined | "undefined" |
| Null | null | "object" |
| Boolean (логический) | true, false | "boolean" |
| Number (числовой) | 42, 3.14, NaN, Infinity | "number" |
| BigInt | 10n | "bigint" |
| String | "hello", пустая строка "" | "string" |
| Symbol | Symbol("id") | "symbol" |
| Object: функция или класс | function () {}, class A {} | "function" |
| Object: всё остальное | {}, [], new Date(), /abc/ | "object" |
Исключений два: у null нет своей строки, а функции, хотя по типу это объекты, получили отдельный "function". Для любого значения, которое можно вызвать, спецификация выдаёт "function", для прочих объектов "object".

Почему typeof null возвращает object
В первой версии JavaScript значение хранилось вместе с меткой типа. У объектов метка была 0, а null представлял нулевой указатель, у которого метка тоже получилась 0. Отсюда typeof null возвращает "object". Исправление на typeof null === "null" для спецификации ECMAScript предлагали, но предложение отклонили.
Проверяйте null строгим сравнением. Если нужен любой объект, кроме null, отсеките его первым условием. Массив, Date и Map такую проверку тоже пройдут:
const user = null;
console.log(typeof user === "object", user !== null && typeof user === "object");
// true false
Массивы, даты и встроенные объекты
Массив, дата, регулярное выражение и встроенный объект Math для typeof одинаковы, а метод Math.max уже функция:
console.log(typeof [1, 2, 3], typeof new Date(), typeof /abc/, typeof Math);
// object object object object
console.log(Array.isArray([1, 2, 3]), typeof Math.max);
// true function
Массив проверяют через Array.isArray(). Для дат и своих классов подходит instanceof: он смотрит цепочку прототипов, поэтому массив для него одновременно Array и Object, а null instanceof Object даёт false.
typeof function, классы и async-функции
Класс для typeof тоже функция, как и async-функция, хотя её вызов возвращает промис:
async function load() { return 1; }
console.log(typeof class User {}, typeof load, typeof load());
// function function object
Проверка typeof callback === "function" перед вызовом защищает от TypeError: callback is not a function, если в параметр передали что-то другое.
typeof NaN: «не число» с типом number
NaN получается, когда арифметика не может дать число. По типу он всё равно остаётся числом, и typeof возвращает "number":
const n = Number("12px");
console.log(n, typeof n); // NaN number
console.log(Number.isNaN(n), isNaN("abc"), Number.isNaN("abc")); // true true false
NaN не равен даже себе, поэтому n === NaN всегда false. Глобальная isNaN() сначала превращает аргумент в число, и строка "abc" у неё тоже считается NaN. Number.isNaN() ничего не преобразует, лучше использовать её. Если нужно обычное конечное число, проверка выглядит так: typeof x === "number" && Number.isFinite(x).
Необъявленная переменная и временная мёртвая зона
typeof для имени, которое нигде не объявлено, возвращает "undefined" без ошибки. Переменная let или const до строки объявления ведёт себя иначе:
console.log(typeof notDeclared); // undefined
try {
console.log(typeof price);
let price = 100;
} catch (error) {
console.log(error.name + ": " + error.message);
}
// ReferenceError: Cannot access 'price' before initialization
Это временная мёртвая зона: до строки let price имя уже занято, но значения ещё нет. Подробно она разобрана в статье про let и const в JavaScript. Проверка необъявленного имени иногда нужна, если один код запускается и в браузере, и в Node.js:
console.log(typeof window, typeof process); // undefined object
const isBrowser = typeof window !== "undefined";
В Node.js window нет, и обращение window.location без такой проверки упало бы с ReferenceError: window is not defined.

Обёртки new String, new Number и new Boolean
Когда у строки вызывают метод, JavaScript на время оборачивает её в объект String. Вручную через new такие обёртки не создают: строгое сравнение со строкой даёт false, а new Boolean(false) в условии истинен.
const a = "text";
const b = new String("text");
console.log(typeof a, typeof b, a === "text", b === "text"); // string object true false
const flag = new Boolean(false);
if (flag) console.log("условие выполнилось, хотя внутри false");
// условие выполнилось, хотя внутри false
Любой объект в условии истинен, даже обёртка над false. Без new те же функции работают как преобразование и возвращают примитив: typeof String(42) даёт "string", typeof Number("42") даёт "number".
Преобразование типов и данные извне
Значение из поля формы, из командной строки или из JSON, например возраст, часто приходит строкой, хотя выглядит как число:
const data = JSON.parse('{"name": "Аня", "age": "25", "score": 7, "phone": null}');
for (const key in data) console.log(key, typeof data[key]);
// name string
// age string
// score number
// phone object
console.log(typeof process.argv[2]); // string (запуск: node app.js 42)
Свойства здесь перебирает цикл for...in. Как устроены циклы, разобрано в статье про циклы while, for и do while.
Оператор * превращает строку в число сам, а + склеивает строки:
console.log("5" * 2, "5" + 2, "5" == 5, "5" === 5); // 10 52 true false
console.log(typeof ("5" * 2), typeof ("5" + 2)); // number string
Нестрогое == приводит типы перед сравнением, строгое === сравнивает и тип, и значение. Мы советуем привести ввод к числу явно через Number() и проверить typeof и Number.isFinite() до вычислений, тогда «52» вместо 7 в сумме не появится.

Функция, чтобы определить тип точнее
Когда нужно отличить null, массив, дату и структуры вроде Map, удобна своя функция. Метод Object.prototype.toString возвращает строку вида [object Date], из неё вырезаем имя:
function getType(value) {
if (value === null) return "null";
if (Array.isArray(value)) return "array";
const type = typeof value;
if (type !== "object") return type;
return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
}
const values = [null, [], new Date(), /x/, {}, new Map(), 5, () => 1];
console.log(values.map(getType).join(" "));
// null array date regexp object map number function
Сам typeof полезен для примитивов и функций, и для них getType() отдаёт его результат как есть. Объект своего класса функция назовёт object, в такой ситуации нужен instanceof.
Частые ошибки с typeof
Сравнение с undefined без кавычек
typeof возвращает строку, а undefined без кавычек это значение, поэтому условие никогда не выполнится:
let value;
console.log(typeof value === undefined); // false
console.log(typeof value === "undefined"); // true
console.log(typeof 5 === "Number"); // false
Третья строка показывает ошибку в регистре: "Number" с большой буквы не совпадёт ни с одним результатом.
Забытые скобки вокруг выражения
У typeof приоритет выше, чем у сложения, поэтому он выполняется первым:
const age = 30;
console.log(typeof age + 1, typeof (age + "1")); // number1 string
Первое выражение взяло тип age и приклеило к нему единицу. Чтобы узнать тип результата, выражение берут в скобки.

Частые вопросы
Чем typeof отличается от instanceof?
typeof возвращает строку с названием типа и работает с любым значением, включая необъявленные имена (но не let и const до объявления). Оператор instanceof возвращает true или false и проверяет, есть ли прототип конструктора в цепочке объекта; для примитивов он даёт false.
Работает ли typeof с BigInt и Symbol?
Да, для них есть свои строки: typeof 10n даёт "bigint", typeof Symbol("id") даёт "symbol". Тип bigint поддерживают все браузеры с сентября 2020 года. Смешать его с обычным числом нельзя: 10n + 1 падает с TypeError: Cannot mix BigInt and other types, use explicit conversions.
Как проверить, что переменная строка?
Для простой проверки хватает typeof x === "string". Строка, созданная через new String(), её не пройдёт, но обычно такие обёртки в коде не встречаются.
Что вернёт typeof для undefined?
Строку "undefined". Так же отвечает оператор для переменной let без значения, для отсутствующего свойства объекта (typeof user.email) и для необъявленного имени.








